/*
(c) Eniris BV, 2026. All rights reserved.

The design of the commissioning interface, in Google's Material Design 3 (Material You): its colour roles, shapes, type
scale, elevation, state layers and motion, laid over the styles of templates/base.html, which links this stylesheet on
every controller.

The colours follow the brand of the controller. Material You derives a whole colour scheme from the colours of a brand,
and so does this stylesheet for the colours that carry the brand: they come from the colours base.html takes from the
license (--primary-color, --secondary-color, --tertiary-color: the whitelabel schema of common/license, or the Eniris
colours of frontend/houseStyle.py). Nothing here names a colour of a brand. A role is the colour of the brand at the
tone of that role in the standard M3 light scheme: a container at tone 90, the text on it at tone 30. Tone is the
lightness of CIELAB, which the lch() colours of CSS share with the HCT colours of Material. A browser without relative
colours gets the roles mixed with color-mix(). The colour of the brand is an accent: the page, its cards, the text and
the lines are the neutral greys of the Eniris BMS (bms.eniris.com), on every controller. The page is light grey, a card
white, and a card in a card has no colour of its own.

- Every solid button is the secondary colour of the brand itself, in both themes, with black text on a light colour and
  white text on a dark one (--md-on-secondary): the colour the license gives the buttons. The outlined buttons of an
  action row (the devices page, the custom Modbus drivers, the communication page) take the primary colour as their
  text, and what is chosen (a tab, a range) the primary colour as its fill: the accent of the brand. A page that gives
  its buttons a background of its own gives them a colour of text of their own too.
- The navigation bar keeps the primary colour of the brand; the page that is open is a pill in the tertiary colour with
  the primary colour as its text: the colours the license gives the bar and its highlight, so just as readable.
- The font is Sora (SIL Open Font License, fonts/OFL.txt); Chinese, Japanese and Korean text keeps the fonts of the
  system.
- Section titles are black and bold. Messages are one colour, without a bar on their edge.
- The motion is that of the Eniris BMS (Motion, at the end): pages fade into each other where the browser can, menus
  and dialogs scale in, the drawer slides in, collapsible boxes unfold.
- The dark theme (html.md-dark, set by base.html before the page is drawn: when the device is set to dark, or the button
  of the bar chose it) is that of the BMS too: its dark greys, and the colours of the brand at the tones of the standard
  M3 dark scheme. A page with colours of its own gives them a dark counterpart under html.md-dark, with the roles below.

Rules that reach into the pages keep the specificity of the rule of base.html they replace, or are wrapped in :where(),
so that whatever a page styles itself still wins.
*/

/* ---- Tokens -------------------------------------------------------------------------------------------------------- */

@font-face {
    font-family: 'Sora';
    font-style: normal;
    font-display: swap;
    font-weight: 100 800;
    src: url('fonts/Sora-latin-ext.woff2') format('woff2-variations'), url('fonts/Sora-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: 'Sora';
    font-style: normal;
    font-display: swap;
    font-weight: 100 800;
    src: url('fonts/Sora-latin.woff2') format('woff2-variations'), url('fonts/Sora-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;
}

:root {
    /* Colour roles of the brand: neutral greys for a browser without color-mix() */
    --md-primary: var(--primary-color);
    --md-on-primary: #FFFFFF;
    --md-secondary-container: #E6E6E6;
    --md-on-secondary-container: #1C1B1B;
    /* The neutral greys of the Eniris BMS (front-end/bms, styles.css): the cards (its surface), the page (its canvas),
       a little darker for what stands out on a card, the text (its ink and muted text) and the lines (its line-strong
       for the frame of a field, 3:1 on white, and its line) */
    --md-surface-container-lowest: #FFFFFF;
    --md-surface-container-low: #F6F7F9;
    --md-surface-container: #F3F4F6;
    --md-on-surface: #111827;
    --md-on-surface-variant: #58606F;
    --md-outline: #8D94A0;
    --md-outline-variant: #E4E7EC;
    /* The shadow of a card of the BMS */
    --md-shadow-card: 0 1px 2px rgba(15, 23, 42, 0.04), 0 0 0 0.5px rgba(15, 23, 42, 0.02);
    /* The titles of the pages and their sections */
    --md-title: #000000;
    /* An icon of the icon font that has no colour of its own (templates/node_icon_font.html) */
    --md-icon: #444455;
    /* A field that the pages grey out themselves (the bulk settings, a read-only field: settings_advanced.py,
       external_signals.py) */
    --md-field-disabled: #D3D3D3;
    /* What goes well or wrong, what warns and what informs: a colour for text and icons, a container (the background of
       a message) and the text on that container. Error = M3; success and warning = the ok and warn of the BMS */
    --md-error: #B3261E;
    --md-error-container: #F9DEDC;
    --md-on-error-container: #410E0B;
    --md-warning: #A84C08;
    --md-warning-container: #FFF4E0;
    --md-on-warning-container: #4D3800;
    --md-success: #047857;
    --md-success-container: #E8F5EC;
    --md-on-success-container: #1B5E20;
    --md-info: #1A73E8;
    --md-info-container: #E8F1FB;
    --md-on-info-container: #0B3A6E;
    /* The text on the secondary colour itself: black on a light colour, white on a dark one (lch() below; without it
       black, the pages were made for a light secondary colour). houseStyle.css sets its own */
    --md-on-secondary: #000000;

    /* The solid buttons: the secondary colour itself, whether a plain button or the main one of a form (the filled
       button of M3), in both themes */
    --md-button: var(--secondary-color);
    --md-on-button: var(--md-on-secondary);
    --md-button-filled: var(--md-button);
    --md-on-button-filled: var(--md-on-button);

    --md-font: 'Sora', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;

    --md-shape-sm: 8px;
    --md-shape-md: 12px;
    --md-shape-lg: 16px;
    --md-shape-full: 9999px;

    --md-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.12), 0 1px 3px 1px rgba(0, 0, 0, 0.06);
    --md-elevation-2: 0 1px 2px rgba(0, 0, 0, 0.14), 0 2px 6px 2px rgba(0, 0, 0, 0.08);
    --md-elevation-3: 0 1px 3px rgba(0, 0, 0, 0.16), 0 4px 8px 3px rgba(0, 0, 0, 0.10);

    /* Short, with the standard easing of M3: the interface answers at once */
    --md-easing: cubic-bezier(0.2, 0, 0, 1);
    --md-duration: 150ms;
    /* What enters (Motion below): the curve and durations of the Eniris BMS (bms.eniris.com, front-end/bms) */
    --md-easing-enter: cubic-bezier(0.2, 0.7, 0.2, 1);
    --md-duration-menu: 180ms;
    --md-duration-fade: 200ms;
    --md-duration-sheet: 220ms;
    --md-duration-expand: 300ms;
    --md-duration-fade-up: 350ms;

    accent-color: var(--md-primary);
    -webkit-tap-highlight-color: transparent;
    color-scheme: light;
}

@supports (color: color-mix(in srgb, red, blue)) {
    :root {
        --md-secondary-container: color-mix(in srgb, var(--secondary-color) 22%, white);
        --md-on-secondary-container: color-mix(in srgb, var(--secondary-color) 40%, black);
    }
}

/* The tones of the standard M3 light scheme (material-color-utilities, SchemeTonalSpot) */
@supports (color: lch(from red min(l, 45) min(c, 16) h)) {
    :root {
        --md-primary: lch(from var(--primary-color) min(l, 45) c h);
        --md-secondary-container: lch(from var(--secondary-color) 90 min(c, 22) h);
        --md-on-secondary-container: lch(from var(--secondary-color) 30 min(c, 40) h);
        /* Black on a light secondary colour, white on a dark one */
        --md-on-secondary: lch(from var(--secondary-color) clamp(0, (65 - l) * 1000, 100) 0 0);
    }
}

/* The dark theme: the dark greys of the BMS (its .dark: the page its canvas, a card its surface, a little lighter its
   raised, the text its ink and muted text, the lines its line-strong and line), and the colours of the brand at the
   tones of the standard M3 dark scheme: the primary colour as a text, an icon or a line at tone 80 (the colour itself is
   too dark on a dark card), the text on it at tone 20, a container at tone 30 with its text at tone 90. The navigation
   bar and the buttons keep the colours of the brand */
html.md-dark {
    color-scheme: dark;
    --md-primary: #D0BCFF;
    --md-on-primary: #1C1B1B;
    --md-secondary-container: #3A3B3E;
    --md-on-secondary-container: #E6E6E6;
    --md-surface-container-lowest: #12151B;
    --md-surface-container-low: #0A0C10;
    --md-surface-container: #181C24;
    --md-on-surface: #ECEFF4;
    --md-on-surface-variant: #A8AFBD;
    --md-outline: #5C6474;
    --md-outline-variant: #262B36;
    /* A dark card: a hairline of light at its top edge and a dark shadow (the .dark .card of the BMS) */
    --md-shadow-card: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 1px 2px rgba(0, 0, 0, 0.4);
    --md-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.5), 0 1px 3px 1px rgba(0, 0, 0, 0.3);
    --md-elevation-2: 0 1px 2px rgba(0, 0, 0, 0.5), 0 2px 6px 2px rgba(0, 0, 0, 0.35);
    --md-elevation-3: 0 1px 3px rgba(0, 0, 0, 0.5), 0 4px 8px 3px rgba(0, 0, 0, 0.4);
    --md-title: #FFFFFF;
    --md-icon: #A8AFBD;
    --md-field-disabled: #181C24;
    /* The bad, warn and ok of the dark theme of the BMS */
    --md-error: #F87171;
    --md-error-container: #4A1616;
    --md-on-error-container: #FECACA;
    --md-warning: #FBBF24;
    --md-warning-container: #3B2A08;
    --md-on-warning-container: #FDE68A;
    --md-success: #34D399;
    --md-success-container: #0D342A;
    --md-on-success-container: #A7F3D0;
    --md-info: #8AB4F8;
    --md-info-container: #10263F;
    --md-on-info-container: #C9DCF7;
    background-color: var(--md-surface-container-low);
}

@supports (color: color-mix(in srgb, red, blue)) {
    html.md-dark {
        --md-primary: color-mix(in srgb, var(--primary-color) 35%, white);
        --md-on-primary: color-mix(in srgb, var(--primary-color) 35%, black);
        --md-secondary-container: color-mix(in srgb, var(--secondary-color) 30%, #12151B);
        --md-on-secondary-container: color-mix(in srgb, var(--secondary-color) 20%, white);
    }
}

@supports (color: lch(from red min(l, 45) min(c, 16) h)) {
    html.md-dark {
        --md-primary: lch(from var(--primary-color) 80 min(c, 50) h);
        --md-on-primary: lch(from var(--primary-color) 20 min(c, 50) h);
        --md-secondary-container: lch(from var(--secondary-color) 30 min(c, 22) h);
        --md-on-secondary-container: lch(from var(--secondary-color) 90 min(c, 16) h);
    }
}

@media (prefers-reduced-motion: reduce) {
    :root {
        --md-duration: 0ms;
        --md-duration-menu: 0ms;
        --md-duration-fade: 0ms;
        --md-duration-sheet: 0ms;
        --md-duration-expand: 0ms;
        --md-duration-fade-up: 0ms;
    }
}

/* ---- Page and text ------------------------------------------------------------------------------------------------- */

body {
    font-family: var(--md-font);
    background-color: var(--md-surface-container-low);
    color: var(--md-on-surface);
    -webkit-font-smoothing: antialiased;
}

/* Form controls do not inherit the font of the page by themselves. Not textareas: the log and metadata windows show
   their text in the monospace font of the browser */
button, input, select {
    font-family: inherit;
}

.help-tip:before, .help-tip p, .lock-badge .lock-text {
    font-family: inherit;
}

/* The titles of the pages and their sections: black and bold (white in the dark theme) */
:where(.maincontent) :where(h1, h2, h3) {
    color: var(--md-title);
    font-weight: bold;
}

:where(.maincontent) a:where(:not([class])) {
    color: var(--md-primary);
}

.brandTempText {
    color: var(--md-primary);
}

:focus-visible {
    outline: 2px solid var(--md-primary);
    outline-offset: 2px;
}

/* ---- Navigation bar and drawer ------------------------------------------------------------------------------------- */

/* The bar stays at the top of the window while the page scrolls under it. What else stays in sight (the sidebars) and
   what the page scrolls to (an item of a settings page in the address, #grid) come under it: base.html keeps its height
   in --md-nav-height (0 without the bar: in a pop-up, embedded) */
.topnav {
    position: sticky;
    top: 0;
    box-shadow: var(--md-elevation-2);
}

html {
    scroll-padding-top: var(--md-nav-height, 0px);
}

.topnav a.logolink {
    margin-right: 24px;
}

/* On a wide screen the items of the bar on a row next to the logo, the language and the logout at its right end */
@media screen and (min-width: 1111px) {
    .topnav > .BigScreen {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        padding-right: 12px;
    }

    /* An item keeps its label on one line: when the bar is too narrow for all of them, the last ones go to a next line */
    .topnav > .BigScreen > * {
        flex: none;
        white-space: nowrap;
    }

    .topnav > .BigScreen > .language-dropdown {
        margin-left: auto;
    }

    .topnav > .BigScreen > .separator {
        margin-top: 0;
    }

    /* Items that do not fit on one row (base.html): first less room around each, then the menu button with the drawer,
       as on a narrower screen (base.html: max-width 1110px) */
    html.md-nav-compact .topnav > .BigScreen > a, html.md-nav-compact .topnav > .BigScreen .language-button {
        padding-left: 8px;
        padding-right: 8px;
    }

    html.md-nav-compact .topnav > .BigScreen > .separator {
        margin-left: 8px;
        margin-right: 8px;
    }

    html.md-nav-drawer .topnav > .BigScreen {
        display: none;
    }

    html.md-nav-drawer .topnav .menuicon {
        float: right;
        display: block;
        margin-right: 40px;
        font-weight: bold;
        transform: scaleX(1.75);
    }
}

/* The items of the bar (not those of the drawer, .sidenav, which sits in .topnav too) */
.topnav > a:not(.logolink):not(.menuicon), .topnav > .BigScreen > a, .topnav > .BigScreen .language-button {
    padding: 10px 16px;
    margin: 12px 2px;
    border-radius: var(--md-shape-full);
    font-size: 15px;
    font-weight: 500;
    line-height: 20px;
    transition: background-color var(--md-duration) var(--md-easing), color var(--md-duration) var(--md-easing);
}

/* No bold under the mouse: the item would grow and push the others aside. A state layer instead */
.topnav > a:not(.logolink):not(.menuicon):hover, .topnav > .BigScreen > a:hover, .topnav > .BigScreen .language-button:hover {
    font-weight: 500;
    background-color: color-mix(in srgb, currentColor 12%, transparent);
}

/* The page that is open: a pill in the highlight colour of the bar, with the colour of the bar as its text. Not the
   empty active item of the pages without navigation (login.html) */
.topnav > .BigScreen > a.active, .topnav > .BigScreen > a.active:hover {
    background-color: var(--tertiary-color);
    color: var(--primary-color);
    font-weight: 600;
}

/* From one page to the next, the pill slides from the page that was open to the one that opens (base.html:
   @view-transition). Each label keeps its size, in the middle of the moving pill */
.topnav > .BigScreen > a.active {
    view-transition-name: nav-pill;
}

::view-transition-group(nav-pill) {
    animation-timing-function: var(--md-easing-enter);
}

::view-transition-old(nav-pill), ::view-transition-new(nav-pill) {
    inline-size: auto;
    block-size: 100%;
    left: 50%;
    translate: -50% 0;
}

.topnav :focus-visible {
    outline-color: currentColor;
}

/* The items of the drawer: one under the other, the full width of the drawer (base.html floats every link of .topnav,
   the drawer included) */
.sidenav a:not(.closebtn), .sidenav .language-dropdown, .sidenav .language-button {
    float: none;
}

.sidenav .language-button {
    width: calc(100% - 24px);
}

.sidenav a:not(.closebtn), .sidenav .language-button {
    padding: 14px 24px;
    margin: 2px 12px;
    border-radius: var(--md-shape-full);
    font-size: 15px;
    font-weight: 500;
    transition: background-color var(--md-duration) var(--md-easing);
}

.sidenav a:not(.closebtn):hover, .sidenav .language-button:hover {
    font-weight: 500;
    background-color: color-mix(in srgb, currentColor 12%, transparent);
}

.sidenav a.active, .sidenav a.active:hover {
    background-color: var(--tertiary-color);
    color: var(--primary-color);
    font-weight: 600;
}

/* The close button of the drawer: a round icon button in its corner, above the first item (base.html put it over the
   right end of the first item, so that a tap there closed the drawer instead of opening that page) */
.sidenav a.closebtn {
    position: absolute;
    top: 10px;
    right: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 40px;
    height: 40px;
    margin: 0;
    padding: 0;
    border-radius: 50%;
    font-size: 28px;
    font-weight: 400;
    line-height: 1;
    transition: background-color var(--md-duration) var(--md-easing);
}

.sidenav a.closebtn:hover {
    font-weight: 400;
    color: #f2f2f2;
    background-color: color-mix(in srgb, currentColor 12%, transparent);
}

/* The drawer is a column that scrolls when its items do not fit; the language and logging out sit at its bottom, under
   a line, as at the right end of the bar on a wide screen (base.html: sidenav-end). The languages open as a list in the
   drawer, set in, under the button with its arrow */
.sidenav {
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    padding-bottom: 12px;
    overflow-y: auto;
}

.sidenav .sidenav-end {
    display: flex;
    flex-direction: column;
    margin-top: auto;
    padding-top: 8px;
    border-top: 1px solid color-mix(in srgb, #f2f2f2 30%, transparent);
}

.sidenav .sidenav-language {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    text-align: left;
}

.sidenav .sidenav-language .gicon-sym {
    transition: transform var(--md-duration) var(--md-easing);
}

.sidenav .sidenav-language[aria-expanded="true"] .gicon-sym {
    transform: rotate(180deg);
}

.sidenav .sidenav-languages {
    display: flex;
    flex-direction: column;
    padding-left: 12px;
}

.sidenav .sidenav-languages[hidden] {
    display: none;
}

.sidenav .sidenav-languages:not([hidden]) {
    animation: md-fade-up var(--md-duration-fade-up) var(--md-easing-enter);
}

.sidenav .sidenav-languages form {
    margin: 0;
}

.sidenav .sidenav-languages button {
    width: calc(100% - 24px);
    margin: 0 12px;
    padding: 10px 24px;
    border: none;
    border-radius: var(--md-shape-full);
    background: transparent;
    box-shadow: none;
    color: #f2f2f2;
    font: inherit;
    font-size: 14px;
    font-weight: 400;
    text-align: left;
    transition: background-color var(--md-duration) var(--md-easing);
}

.sidenav .sidenav-languages button:hover {
    opacity: 1;
    background-color: color-mix(in srgb, #f2f2f2 12%, transparent);
    box-shadow: none;
}

/* The button of the colours of the pages (base.html): a round icon button on the bar, before the language, which then
   no longer pushes itself to the right end; in the drawer an item like the language. It shows the theme it goes to: the
   moon in the light theme, the sun in the dark one */
html:not(.md-dark) .md-when-dark, html.md-dark .md-when-light {
    display: none !important;
}

.md-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.topnav .md-theme-button {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 40px;
    height: 40px;
    margin: 12px 2px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    box-shadow: none;
    color: #f2f2f2;
    font-size: 22px;
    cursor: pointer;
    transition: background-color var(--md-duration) var(--md-easing);
}

.topnav .md-theme-button:hover {
    opacity: 1;
    background-color: color-mix(in srgb, currentColor 12%, transparent);
    box-shadow: none;
}

.topnav .md-theme-button .gicon-sym {
    font-size: 22px;
}

@media screen and (min-width: 1111px) {
    .topnav > .BigScreen > .md-theme-button {
        margin-left: auto;
    }

    .topnav > .BigScreen > .md-theme-button + .language-dropdown {
        margin-left: 0;
    }
}

.sidenav .sidenav-theme {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    text-align: left;
}

/* The language menu: an M3 menu, white like the menus of the BMS */
.language-menu {
    background-color: var(--md-surface-container-lowest);
    border-radius: var(--md-shape-md);
    box-shadow: var(--md-elevation-2);
    padding: 8px 0;
    width: 180px;
    overflow-y: auto;
}

/* By its id: the languages are plain submit buttons, which would otherwise be filled buttons */
#language-menu button {
    color: var(--md-on-surface);
    background-color: transparent;
    border-radius: 0;
    margin: 0;
    padding: 12px 16px;
    font-size: 14px;
    font-weight: 400;
    box-shadow: none;
    transition: background-color var(--md-duration) var(--md-easing);
}

#language-menu button:hover {
    color: var(--md-on-surface);
    font-weight: 400;
    background-color: color-mix(in srgb, var(--md-on-surface) 8%, transparent);
}

/* ---- Buttons ------------------------------------------------------------------------------------------------------- */

/* The buttons in the secondary colour (--md-button): base.html styles every button, so does this (pages that style
   their own buttons win) */
button, input[type=file] + label, .slimbutton, .refreshbutton,
#addition, .additionButton, #subtraction, .subtractButton {
    background-color: var(--md-button);
    color: var(--md-on-button);
    border: 1px solid transparent;
    border-radius: var(--md-shape-full);
    padding: 9px 24px;
    font-size: 14px;
    font-weight: 500;
    line-height: 20px;
    letter-spacing: 0.1px;
    transition: background-color var(--md-duration) var(--md-easing), box-shadow var(--md-duration) var(--md-easing),
        color var(--md-duration) var(--md-easing);
}

.slimbutton {
    padding: 5px 16px;
}

/* The + and - of the rows of a form (the schedules, the state of charge planning, the PV installation, the email alarms):
   round icon buttons of one size, the icon of the font in the middle. Their own text (+, -) stays for a screen reader;
   words with it (on a phone: sched-mobile-text of the schedules, pv-mobile-text of the PV installation) show next to the
   icon. No gap: that text, of no width, is an item of the row too, and a gap would push the icon out of the middle */
#addition, .additionButton, #subtraction, .subtractButton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    min-width: 40px;
    height: 40px;
    margin: 6px 0;
    padding: 0;
    font-size: 0;
    line-height: 1;
    vertical-align: middle;
}

#addition::before, .additionButton::before, #subtraction::before, .subtractButton::before {
    content: '\e145';
    font-family: 'Material Symbols Groups';
    font-size: 22px;
    font-weight: normal;
}

#subtraction::before, .subtractButton::before {
    content: '\e15b';
}

:is(#addition, .additionButton, #subtraction, .subtractButton) :is(.sched-mobile-text, .pv-mobile-text) {
    margin-left: 8px;
    font-size: 14px;
}

/* The main action of a form (the filled button of M3): the same colour as the other buttons */
button[type=submit]:not([class]):not(:disabled) {
    background-color: var(--md-button-filled);
    color: var(--md-on-button-filled);
}

/* The state layer of M3 under the mouse and when pressed, instead of the fading of base.html */
button:not([class]):hover, input[type=file] + label:hover, .slimbutton:hover, .refreshbutton:hover,
#addition:hover, .additionButton:hover, #subtraction:hover, .subtractButton:hover {
    opacity: 1;
    background-color: var(--md-button);
    color: var(--md-on-button);
    background-image: linear-gradient(color-mix(in srgb, currentColor 8%, transparent), color-mix(in srgb, currentColor 8%, transparent));
    box-shadow: var(--md-elevation-1);
}

button[type=submit]:not([class]):not(:disabled):hover {
    background-color: var(--md-button-filled);
    color: var(--md-on-button-filled);
}

button:not([class]):active, input[type=file] + label:active, .slimbutton:active, .refreshbutton:active,
#addition:active, .additionButton:active, #subtraction:active, .subtractButton:active {
    background-image: linear-gradient(color-mix(in srgb, currentColor 12%, transparent), color-mix(in srgb, currentColor 12%, transparent));
    box-shadow: none;
}

/* M3 outlined buttons, in a row: the buttons of each driver on the custom Modbus drivers page, the actions of each
   device on the devices page (its forms and links laid out in a wrapping row) and the tools of the communication page */
.device-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 6px;
}

.device-actions > form, .device-actions > div, .device-actions > a {
    display: inline-flex;
    margin: 0;
}

/* Like .cm-row-actions: no underline from the links around the buttons, and one line per button */
.device-actions a {
    text-decoration: none;
}

.device-actions .slimbutton {
    white-space: nowrap;
}

.cm-list .cm-row-actions .slimbutton, .device-actions .slimbutton, .comm-tools .slimbutton {
    background-color: var(--md-surface-container-lowest);
    color: var(--md-primary);
    border: 1px solid var(--md-outline);
    box-shadow: none;
}

.device-actions .slimbutton {
    margin: 0;
}

.cm-list .cm-row-actions .slimbutton:hover, .device-actions .slimbutton:hover, .comm-tools .slimbutton:hover {
    background-color: var(--md-surface-container-lowest);
    color: var(--md-primary);
    background-image: linear-gradient(color-mix(in srgb, var(--md-primary) 8%, transparent), color-mix(in srgb, var(--md-primary) 8%, transparent));
    box-shadow: none;
}

.cm-list .cm-row-actions .slimbutton:disabled, .device-actions .slimbutton:disabled {
    background-color: transparent;
    background-image: none;
    color: color-mix(in srgb, var(--md-on-surface) 38%, transparent);
    border-color: color-mix(in srgb, var(--md-on-surface) 12%, transparent);
}

button:disabled, button:disabled:hover {
    background-color: color-mix(in srgb, var(--md-on-surface) 12%, transparent);
    color: color-mix(in srgb, var(--md-on-surface) 38%, transparent);
    background-image: none;
    box-shadow: none;
    opacity: 1;
    cursor: not-allowed;
}

/* ---- Text fields --------------------------------------------------------------------------------------------------- */

/* M3 outlined text fields */
input[type=text], input[type=password], .text-input, .dropdown-menu, .dropdown-menu-half-width {
    border: 1px solid var(--md-outline);
    border-radius: var(--md-shape-md);
    background-color: var(--md-surface-container-lowest);
    color: var(--md-on-surface);
    padding: 12px 16px;
    transition: border-color var(--md-duration) var(--md-easing), box-shadow var(--md-duration) var(--md-easing);
}

input[type=text]:hover, input[type=password]:hover, .text-input:hover, .dropdown-menu:hover, .dropdown-menu-half-width:hover {
    border-color: var(--md-on-surface);
}

input[type=text]:focus, input[type=password]:focus, .text-input:focus, .dropdown-menu:focus, .dropdown-menu-half-width:focus {
    outline: none;
    border-color: var(--md-primary);
    box-shadow: inset 0 0 0 1px var(--md-primary);
}

.text-input:disabled, input[type=text]:disabled {
    background-color: color-mix(in srgb, var(--md-on-surface) 4%, transparent);
    border-color: color-mix(in srgb, var(--md-on-surface) 12%, transparent);
    color: color-mix(in srgb, var(--md-on-surface) 50%, transparent);
}

/* A field with its name and unit around it: one outlined field (the inputs inside it have no frame of their own) */
.form-group {
    border: 1px solid var(--md-outline);
    border-radius: var(--md-shape-md);
    background-color: var(--md-surface-container-lowest);
    transition: border-color var(--md-duration) var(--md-easing), box-shadow var(--md-duration) var(--md-easing);
}

.form-group:hover {
    border-color: var(--md-on-surface);
}

.form-group:focus-within {
    border-color: var(--md-primary);
    box-shadow: inset 0 0 0 1px var(--md-primary);
}

.form-group input, .form-group select {
    border: none;
    border-right: 1px solid var(--md-outline-variant);
    border-radius: 0;
    background-color: transparent;
    box-shadow: none;
}

.form-group input:focus, .form-group select:focus {
    background-color: transparent;
    box-shadow: none;
}

.form-group label {
    font-weight: 500;
    color: var(--md-on-surface-variant);
}

.advancedEl {
    border-color: var(--md-outline-variant);
    border-radius: var(--md-shape-md);
}

/* ---- Cards --------------------------------------------------------------------------------------------------------- */

/* The cards of the BMS: white, with a hairline frame, on the grey page */
.functionbox, .functionbox-table, .loginform {
    background-color: var(--md-surface-container-lowest);
    border: 1px solid var(--md-outline-variant);
    border-radius: var(--md-shape-lg);
    box-shadow: var(--md-shadow-card);
    padding: 16px 24px;
}

/* A card in a card has no colour of its own: only its frame */
.functionbox .functionbox, .functionbox .functionbox-table, .functionbox-table .functionbox {
    background-color: transparent;
    box-shadow: none;
}

@media screen and (max-width: 640px) {
    .functionbox {
        padding: 12px 14px;
    }

    .functionbox-table {
        padding: 10px 10px;
    }
}

/* The tiles of the wizards: outlined cards that rise under the mouse */
.imageItem, .providerImageItem {
    background-color: var(--md-surface-container-lowest);
    border: 1px solid var(--md-outline-variant);
    border-radius: var(--md-shape-lg);
    transition: box-shadow var(--md-duration) var(--md-easing), border-color var(--md-duration) var(--md-easing);
}

/* Every tile of a list as large as the others, whatever the size of its picture: columns of the same width (two on a
   phone), the rows of the kinds of devices and signals as high as the highest, the logos of the brands and providers in
   tiles of the shape of a logo (938 x 626, 3:2). The picture fits in the middle of its tile */
.imageList {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
    grid-auto-rows: 1fr;
    gap: 12px;
}

.imageList:has(> .providerImageItem) {
    grid-auto-rows: auto;
}

@media screen and (max-width: 640px) {
    .imageList {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }
}

.imageList .imageItem {
    min-width: 0;
    min-height: 0;
    box-sizing: border-box;
    display: flex;
}

/* The picture in the middle of the tile above its name, whose button starts at the same height in every tile (a name of
   two lines does not lift the picture). One column as wide as the tile: a long word in the name does not widen it */
.imageList .imageItem > a {
    flex: 1;
    min-width: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) minmax(64px, auto);
    justify-items: center;
    align-items: center;
    gap: 12px;
    padding: 12px 4px 4px;
    text-decoration: none;
}

/* A name wider than its tile wraps inside it, also a single word ("Gebouwbeheersysteem" in two tiles next to each other
   on a phone): at a syllable with a hyphen where the browser can hyphenate the language of the page (lang of base.html),
   else where the word reaches the edge. Only a word of 10 letters or more is broken at a syllable */
.imageList .imageItem > a > button {
    align-self: start;
    overflow-wrap: anywhere;
    -webkit-hyphens: auto;
    hyphens: auto;
    hyphenate-limit-chars: 10 4 4;
}

/* A second line under the name of a tile, smaller (the relays that the "Digital output" tile also adds) */
.imageList .imageItem .imageItemSubtitle {
    display: block;
    font-size: 0.85em;
    font-weight: normal;
    opacity: 0.85;
}

/* A drawing without room of its own around it (the kinds of signals) gets it in its tile, as the drawings of the kinds
   of devices have */
.imageList .imageItem .flexLink.flexLink-inset {
    box-sizing: border-box;
    padding: 28px;
}

/* Two tiles next to each other on a phone: the names smaller, on two lines where they must */
@media screen and (max-width: 640px) {
    .imageList .imageItem > a > button {
        padding: 8px 12px;
        font-size: 13px;
        line-height: 18px;
    }

    .imageList .imageItem .flexLink.flexLink-inset {
        padding: 16px;
    }
}

.imageList .imageItem > a > br {
    display: none;
}

.imageList .imageItem .flexLink {
    width: 100%;
    height: clamp(96px, 15vw, 190px);
    max-width: none;
    max-height: none;
    object-fit: contain;
}

.imageList .imageItem button {
    max-width: 100%;
}

.imageList .providerImageItem {
    min-width: 0;
    max-width: none;
    min-height: 0;
    max-height: none;
    box-sizing: border-box;
    aspect-ratio: 3 / 2;
}

.imageList .providerImageItem > a {
    position: absolute;
    inset: 12px;
    width: auto;
}

.imageList .providerImageItem .flexImage {
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    margin: 0;
    object-fit: contain;
}

/* The lock of a locked provider over its logo, so that its text still opens under the mouse */
.imageList .providerImageItem .lock-badge {
    z-index: 1;
}

.imageItem:hover, .providerImageItem:hover {
    border-color: transparent;
    box-shadow: var(--md-elevation-2);
}

/* The collapsible title bars of the device settings: no colour of their own on the card, a frame, and a state layer
   under the mouse */
.functionbox .InverterTitle, .functionbox .InverterTitle:hover {
    background-color: transparent;
    border: 1px solid var(--md-outline-variant);
    border-radius: var(--md-shape-md);
    transition: background-image var(--md-duration) var(--md-easing);
}

.functionbox .InverterTitle:hover {
    background-image: linear-gradient(color-mix(in srgb, var(--md-on-surface) 4%, transparent), color-mix(in srgb, var(--md-on-surface) 4%, transparent));
}

.functionbox .InverterTitle h3 {
    color: var(--md-title);
    font-weight: bold;
}

.logwindow, .metadatawindow {
    border-color: var(--md-outline-variant);
    border-radius: var(--md-shape-md);
}

/* ---- Tables, pagination, collapsibles ------------------------------------------------------------------------------ */

.devicestable, .devicestable-responsive th, .devicestable-responsive td {
    border-bottom: 1px solid var(--md-outline-variant);
}

.devicestable-responsive thead th, .devicestable-responsive thead td {
    border-bottom: 1px solid var(--md-outline);
    color: var(--md-on-surface-variant);
    font-weight: 500;
    font-size: 14px;
}

.devicestable-responsive tbody tr > td {
    transition: background-color var(--md-duration) var(--md-easing);
}

.devicestable-responsive tbody tr:hover > td {
    background-color: color-mix(in srgb, var(--md-on-surface) 3%, transparent);
}

.inactivecell {
    background-color: var(--md-surface-container);
}

.pagination li a {
    border: none;
    border-radius: var(--md-shape-full);
    min-width: 40px;
    padding: 10px 12px;
    box-sizing: border-box;
    text-align: center;
    color: var(--md-on-surface-variant);
    background-color: transparent;
    transition: background-color var(--md-duration) var(--md-easing);
}

.pagination li a:hover, .pagination li a:focus {
    background-color: color-mix(in srgb, var(--md-on-surface) 8%, transparent);
}

.pagination li.active a {
    background-color: var(--md-primary);
    color: var(--md-on-primary);
}

/* The state layer of a collapsible title reaches 10px beyond it on both sides: its text stays where it was */
summary {
    padding: 6px 10px;
    margin-left: -10px;
    margin-right: -10px;
    border-radius: var(--md-shape-sm);
    transition: background-color var(--md-duration) var(--md-easing);
}

summary:hover {
    opacity: 1;
    background-color: color-mix(in srgb, currentColor 8%, transparent);
}

/* ---- Settings pages: a sidebar on a wide screen, a list on a narrow one -------------------------------------------- */

/* The settings pages (settings.html, with settings_advanced.html in it, and about.html) and the groups pages
   (groups_*.html): a list with an item per section or group of sections (base.html). On a wide screen it is a sidebar
   with the chosen sections next to it (settings-paged); on a narrow screen (settings-phone) it is the page, like the list
   of the devices page, until an item is chosen (settings-chosen), whose sections then have the page with a way back to
   the list on top. Without the script, the sections are collapsible boxes one under the other */
.settings-nav, .settings-back {
    display: none;
}

/* While the page is read (base.html: md-loading), the sections show only once the script has laid them out: not first
   one under the other, then next to the sidebar or as a list. Without that script they show when the page is read.
   The same for the devices page and its sidebar (static/devices/devices.js: devices-ready), here because its own
   stylesheet comes only with the page: not first every device one under the other, nor the devices in another order */
html.md-loading .settings-layout:not(.settings-paged, .settings-phone),
html.md-loading .devices-layout:not(.devices-ready) {
    visibility: hidden;
}

.settings-layout.settings-paged {
    display: grid;
    grid-template-columns: 248px minmax(0, 1fr);
    gap: 24px;
    align-items: start;
}

.settings-paged .settings-nav {
    position: sticky;
    top: calc(var(--md-nav-height, 0px) + 16px);
    max-height: calc(100vh - var(--md-nav-height, 0px) - 32px);
    overflow-y: auto;
    margin: 10px 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.settings-phone:not(.settings-chosen) .settings-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.settings-phone:not(.settings-chosen) .settings-sections {
    display: none;
}

.settings-paged .settings-section:not(.settings-current), .settings-phone .settings-section:not(.settings-current) {
    display: none;
}

/* The way back to the list, like that of the devices page (devices.css: devices-back) */
.settings-phone.settings-chosen .settings-back {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 4px 0;
    padding: 8px 12px 8px 4px;
    border-radius: var(--md-shape-full);
    color: var(--md-on-surface);
    font-weight: 600;
    text-decoration: none;
    transition: background-color var(--md-duration) var(--md-easing);
}

.settings-phone.settings-chosen .settings-back:hover {
    background-color: color-mix(in srgb, var(--md-on-surface) 6%, transparent);
}

/* The title of a section wraps next to its arrow, not under it (the pages give it display: inline-block) */
.settings-section > summary > :is(h2, h3) {
    display: inline !important;
}

/* The chosen sections are open, their title is only a title (base.html ignores a click on it). The lock of a function
   the license does not include still shows what it means under the mouse */
:is(.settings-paged, .settings-phone) .settings-section > summary {
    pointer-events: none;
    list-style: none;
}

:is(.settings-paged, .settings-phone) .settings-section > summary .lock-badge {
    pointer-events: auto;
}

:is(.settings-paged, .settings-phone) .settings-section > summary::-webkit-details-marker {
    display: none;
}

/* The items of the sidebar of the BMS: grey text, a state layer under the mouse, and the chosen one white like the
   cards it shows, with a bar and its icon in the colour of the brand */
.settings-nav a {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 40px;
    padding: 8px 12px;
    box-sizing: border-box;
    border-radius: var(--md-shape-md);
    color: var(--md-on-surface-variant);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.3;
    text-decoration: none;
    transition: background-color var(--md-duration) var(--md-easing), color var(--md-duration) var(--md-easing);
}

.settings-nav a:hover {
    background-color: color-mix(in srgb, var(--md-on-surface) 5%, transparent);
    color: var(--md-on-surface);
}

.settings-nav a[aria-current] {
    background-color: var(--md-surface-container-lowest);
    color: var(--md-on-surface);
    font-weight: 600;
    box-shadow: var(--md-shadow-card), 0 0 0 1px var(--md-outline-variant);
}

.settings-nav a[aria-current]::before {
    content: '';
    position: absolute;
    left: 0;
    top: 9px;
    bottom: 9px;
    width: 3px;
    border-radius: 3px;
    background-color: var(--md-primary);
}

.settings-nav .gicon-sym {
    flex: none;
    width: 20px;
    font-size: 20px;
    text-align: center;
}

.settings-nav a[aria-current] .gicon-sym {
    color: var(--md-primary);
}

/* A part of the page (the advanced settings) and the pages of their own (about) come last, each under a line; a page
   of its own with an arrow */
.settings-nav .settings-nav-divider {
    flex: none;
    height: 1px;
    margin: 8px 12px;
    background-color: var(--md-outline-variant);
}

/* A part of the page: a title like an item, with an arrow that turns when it opens, and its items under it, set in */
.settings-nav button.settings-nav-part {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 40px;
    margin: 0;
    padding: 8px 12px;
    box-sizing: border-box;
    border: none;
    border-radius: var(--md-shape-md);
    background: transparent;
    box-shadow: none;
    color: var(--md-on-surface-variant);
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
    text-align: left;
    cursor: pointer;
    transition: background-color var(--md-duration) var(--md-easing), color var(--md-duration) var(--md-easing);
}

.settings-nav button.settings-nav-part:hover {
    opacity: 1;
    background-color: color-mix(in srgb, var(--md-on-surface) 5%, transparent);
    color: var(--md-on-surface);
}

.settings-nav .settings-nav-part-arrow {
    margin-left: auto;
    transition: transform var(--md-duration) var(--md-easing);
}

.settings-nav button.settings-nav-part[aria-expanded="true"] .settings-nav-part-arrow {
    transform: rotate(180deg);
}

.settings-nav .settings-nav-part-items {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-left: 12px;
}

.settings-nav .settings-nav-part-items:not([hidden]) {
    animation: md-fade-up var(--md-duration-fade-up) var(--md-easing-enter);
}

/* Without the script the part has a title and its warning (settings_advanced.html) over its boxes, under a line; with
   it the list names it, and the warning shows over the chosen item of the part only */
.settings-part {
    margin-top: 24px;
    padding-top: 8px;
    border-top: 1px solid var(--md-outline-variant);
}

.settings-part-title {
    display: flex;
    align-items: center;
    gap: 8px;
}

:is(.settings-paged, .settings-phone) .settings-part {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
}

:is(.settings-paged, .settings-phone) :is(.settings-part-title, .settings-part:not(.settings-part-current) > .settings-part-intro) {
    display: none;
}

.settings-nav .settings-nav-away {
    margin-left: auto;
    font-size: 18px;
    opacity: 0.7;
}

/* The triangle after an item whose sections show a warning (base.html), as after a device with a warning on the devices
   page (devices.css: devices-item-warning), also on the chosen item. On the title of a part it takes the place of the
   icon, and only while the part is closed: next to its arrow the title has no room for it */
.settings-nav .settings-nav-warning,
.settings-nav a[aria-current] .settings-nav-warning {
    width: auto;
    margin-left: auto;
    font-size: 18px;
    color: #b45309;
}

html.md-dark .settings-nav .settings-nav-warning,
html.md-dark .settings-nav a[aria-current] .settings-nav-warning {
    color: var(--md-warning);
}

.settings-nav button.settings-nav-part .settings-nav-warning {
    width: 20px;
    margin-left: 0;
    font-size: 20px;
}

.settings-nav button.settings-nav-part[aria-expanded="false"] .settings-nav-warning + .gicon-sym,
.settings-nav button.settings-nav-part[aria-expanded="true"] .settings-nav-warning {
    display: none;
}

/* The search field on top of a sidebar (base.html: data-search): a pill like the search bars of M3, its icon inside */
.settings-nav-search {
    flex: none;
    position: relative;
    display: block;
    margin: 0 0 8px;
}

.settings-nav-search .gicon-sym {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--md-on-surface-variant);
    pointer-events: none;
}

.settings-nav-search input[type=search] {
    width: 100%;
    height: 40px;
    margin: 0;
    padding: 0 12px 0 42px;
    box-sizing: border-box;
    border: 1px solid var(--md-outline-variant);
    border-radius: 20px;
    background-color: var(--md-surface-container-lowest);
    color: var(--md-on-surface);
    font: inherit;
    font-size: 14px;
    transition: border-color var(--md-duration) var(--md-easing), box-shadow var(--md-duration) var(--md-easing);
}

.settings-nav-search input[type=search]:hover {
    border-color: var(--md-outline);
}

.settings-nav-search input[type=search]:focus {
    outline: none;
    border-color: var(--md-primary);
    box-shadow: inset 0 0 0 1px var(--md-primary);
}

.settings-nav .settings-nav-empty {
    padding: 8px 12px;
    color: var(--md-on-surface-variant);
    font-size: 14px;
}

.settings-nav [hidden] {
    display: none !important;
}

/* A page under another one (advanced settings, about): an arrow back in front of its title */
.md-title-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin: 0 4px 0 -8px;
    border-radius: 50%;
    color: inherit;
    vertical-align: middle;
    text-decoration: none;
    transition: background-color var(--md-duration) var(--md-easing);
}

.md-title-back:hover {
    background-color: color-mix(in srgb, var(--md-on-surface) 8%, transparent);
}

.md-title-back .gicon-sym {
    font-size: 24px;
}

/* ---- Trees like the one-line diagram ------------------------------------------------------------------------------ */

/* A node: its icon and its name (the devices page: the parts of a device, with their wires drawn by
   static/devices/devices.js; the groups pages: the installation, groups_one_line.html). The first line of the name is as
   high as the box of the icon, so that a wire reaches the middle of the icon, also when the name takes two lines */
.md-tree-head {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 8px 0 4px;
    font-weight: 600;
    line-height: 24px;
}

.md-tree-head > .gicon-sym {
    flex: none;
    width: 20px;
    height: 24px;
    margin: 0;
    font-size: 20px;
    line-height: 24px;
    text-align: center;
    color: var(--md-on-surface-variant);
}

.md-tree-name {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* A tree of nested lists in a tonal panel, each level a step in, with still lines in the colour of the brand: from just
   under the icon of a node down to the last node under it, and into each of those. From the head above: the middle of
   an icon is 10px from the left of its node and 20px from its top, the bottom of the glyph 30px from its top, the nodes
   under it start 36px from its top; a level is 28px further in; a line stops 3px under an icon and 5px before one */
.md-tree-panel {
    padding: 4px 16px 8px;
    border-radius: var(--md-shape-md);
    background-color: var(--md-surface-container);
    overflow-x: auto;
}

.md-tree, .md-tree ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.md-tree ul {
    padding-left: 28px;
}

.md-tree li {
    position: relative;
    margin: 0;
    padding: 0;
}

/* The line down: past the node to the next one, into the middle of the last one */
.md-tree li li::before {
    content: '';
    position: absolute;
    left: -19px;
    top: -3px;
    bottom: 0;
    width: 2px;
    border-radius: 1px;
    background-color: var(--md-primary);
}

.md-tree li li:last-child::before {
    bottom: auto;
    height: 24px;
}

/* The line into the node */
.md-tree li li::after {
    content: '';
    position: absolute;
    left: -18px;
    top: 19px;
    width: 13px;
    height: 2px;
    border-radius: 1px;
    background-color: var(--md-primary);
}

/* The line down from a node with nodes under it starts just under its icon, also when its name takes more lines: down
   the side of the rest of its head, to where the line of the first node under it starts (3px above it). Its middle is
   that of the line of the nodes under it: a level in (28px) and 19px back out */
.md-tree li:has(> ul > li) > .md-tree-head {
    position: relative;
}

.md-tree li:has(> ul > li) > .md-tree-head::after {
    content: '';
    position: absolute;
    left: 9px;
    top: 33px;
    bottom: 0;
    width: 2px;
    border-radius: 1px;
    background-color: var(--md-primary);
}

/* ---- A page in a window over another page ------------------------------------------------------------------------- */

/* The window in which an action opens (base.html: data-popout; the actions of a device, the two-factor
   authentication): a card over the page, which is blurred behind it, with the page of the action in it. It takes most
   of the screen: the page in it lays itself out for the width of the window, and a table of a page (base.html:
   devicestable-responsive) only stays a table from 1111px on. A narrow one (data-popout-size="narrow") for a page of a
   few fields */
.md-popout {
    width: min(1440px, calc(100vw - 48px));
    max-width: none;
    max-height: calc(100dvh - 48px);
    padding: 0;
    border: none;
    border-radius: var(--md-shape-lg);
    background-color: var(--md-surface-container-low);
    color: var(--md-on-surface);
    box-shadow: var(--md-elevation-3);
    overflow: hidden;
}

.md-popout.md-popout-narrow {
    width: min(640px, calc(100vw - 48px));
}

.md-popout[open] {
    display: flex;
    flex-direction: column;
}

.md-popout::backdrop {
    background-color: rgba(17, 24, 39, 0.35);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}

.md-popout-head {
    flex: none;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 8px 8px 24px;
    background-color: var(--md-surface-container-lowest);
    border-bottom: 1px solid var(--md-outline-variant);
}

/* The title wraps when it is wider than the window (a phone: the action and a long name of a device) */
.md-popout-head h3 {
    flex: 1;
    min-width: 0;
    margin: 0;
    overflow-wrap: anywhere;
}

.md-popout .md-popout-close {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--md-on-surface-variant);
    box-shadow: none;
    cursor: pointer;
}

.md-popout .md-popout-close:hover {
    background-color: color-mix(in srgb, var(--md-on-surface) 8%, transparent);
    color: var(--md-on-surface);
}

.md-popout .md-popout-close .gicon-sym {
    margin: 0;
    font-size: 22px;
}

/* As high as the page in it (base.html), less when the screen is not that high: the page then scrolls */
.md-popout-frame {
    flex: 0 1 auto;
    width: 100%;
    height: 320px;
    min-height: 0;
    border: none;
    background-color: var(--md-surface-container-low);
}

/* The page behind the window does not scroll while it is open */
html:has(.md-popout[open]) {
    overflow: hidden;
}

/* The page in the window (base.html: md-in-popout): no navigation bar, and less room around it */
.md-in-popout .topnav, .md-in-popout .sidenav, .md-in-popout body::after {
    display: none !important;
}

.md-in-popout .maincontent {
    margin: 16px !important;
    padding-top: 0 !important;
}

/* A page of a few fields in the window (the name of a device, its other actions, its driver inputs, the two-factor
   authentication): the window is its card, white, with what the card holds right in it; a card in that card keeps its
   frame. A page of cards (the device settings: data-popout-look="cards" on the page, base.html) keeps them on the grey,
   as do the window while it loads such a page (md-popout-cards, from data-popout-look on the action) */
.md-popout:not(.md-popout-cards), .md-popout:not(.md-popout-cards) .md-popout-frame {
    background-color: var(--md-surface-container-lowest);
}

html.md-in-popout:not([data-popout-look="cards"]) body {
    background-color: var(--md-surface-container-lowest);
}

html.md-in-popout:not([data-popout-look="cards"]) .maincontent {
    margin: 20px 24px !important;
}

html.md-in-popout:not([data-popout-look="cards"]) .maincontent :is(.functionbox, .functionbox-table):not(:is(.functionbox, .functionbox-table) *) {
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    background-color: transparent;
    box-shadow: none;
}

@media screen and (max-width: 600px) {
    .md-popout, .md-popout.md-popout-narrow {
        width: 100vw;
        height: 100dvh;
        max-height: 100dvh;
        border-radius: 0;
    }

    .md-popout-frame {
        flex-grow: 1;
    }
}

/* ---- Messages and tooltips ----------------------------------------------------------------------------------------- */

/* One colour for the whole message: no bar on its edge */
.setting-info, .static-setting-info, .setting-warning, .driver-update-info, .test-required-warning, .warning-div,
.device-setting-warning {
    border: none;
    border-radius: var(--md-shape-md);
    padding: 10px 16px;
}

/* A row of the device settings with a remark of the check of the settings (devices_settings.html,
   devices_physical_settings.html): in the colour of its kind, a warning over an info */
tr.setting-row-info {
    background-color: #eef9fd;
}

tr.setting-row-warning {
    background-color: #fff3cd;
}

/* An icon of the icon library in a message (the warning triangle of the settings checks), on its line of text */
:is(.setting-info, .static-setting-info, .setting-warning, .driver-update-info, .test-required-warning, .warning-div) .gicon-sym {
    font-size: 1.3em;
    vertical-align: -0.28em;
    margin-right: 6px;
    color: inherit;
}

.help-tip {
    border: 1.5px solid var(--md-on-surface-variant);
}

.help-tip:before {
    color: var(--md-on-surface-variant);
}

/* M3 rich tooltips, white like the popovers of the BMS */
.help-tip p, .lock-badge .lock-text {
    background-color: var(--md-surface-container-lowest);
    color: var(--md-on-surface-variant);
    border: none;
    border-radius: var(--md-shape-md);
    box-shadow: var(--md-elevation-2);
}

.help-tip p a {
    color: var(--md-primary);
    text-decoration: underline;
}

#update-overlay > div {
    background-color: var(--md-surface-container-lowest);
    border-radius: var(--md-shape-lg);
    box-shadow: var(--md-elevation-3);
}

/* ---- The dark theme of what base.html and the shared templates colour themselves ------------------------------------ */

/* The messages: the containers of their kind (light: the colours of base.html) */
html.md-dark :is(.setting-warning, .warning-div, .device-setting-warning) {
    background-color: var(--md-warning-container);
    color: var(--md-on-warning-container);
}

html.md-dark :is(.setting-info, .static-setting-info, .driver-update-info) {
    background-color: var(--md-info-container);
    color: var(--md-on-info-container);
}

html.md-dark .test-required-warning {
    background-color: var(--md-error-container);
    color: var(--md-on-error-container);
}

/* The rows of the device settings with a remark: the light colours under the light text of the dark theme could hardly
   be read */
html.md-dark tr.setting-row-info {
    background-color: var(--md-info-container);
}

html.md-dark tr.setting-row-warning {
    background-color: var(--md-warning-container);
}

/* What the license locks: its red lock, and its controls greyed (base.html marks them !important) */
html.md-dark :is(.lock-badge, .lock-badge .gicon-sym, .gicon-sym.lock-glyph) {
    color: var(--md-error);
}

html.md-dark .lock-control, html.md-dark .lock-control:hover {
    background-color: color-mix(in srgb, var(--md-on-surface) 6%, transparent) !important;
    color: color-mix(in srgb, var(--md-on-surface) 45%, transparent) !important;
    border-color: color-mix(in srgb, var(--md-on-surface) 14%, transparent) !important;
}

/* A button that cannot be used yet (the restore of a backup before a file is chosen) */
html.md-dark #restore-button:disabled {
    background-color: color-mix(in srgb, var(--md-on-surface) 12%, transparent);
    color: color-mix(in srgb, var(--md-on-surface) 38%, transparent);
}

html.md-dark .file-name {
    color: var(--md-on-surface-variant);
}

html.md-dark .file-name.file-required-error {
    color: var(--md-error);
}

/* A table that stacks on a phone: the line between its rows and the name before each value */
@media screen and (max-width: 1110px) {
    html.md-dark .devicestable-responsive tr {
        border-bottom-color: var(--md-outline-variant);
    }

    html.md-dark .devicestable-responsive td:before {
        color: var(--md-on-surface-variant);
    }
}

html.md-dark .pagination li.disabled a {
    color: color-mix(in srgb, var(--md-on-surface) 38%, transparent);
}

html.md-dark :is(.box, .imagecolumn, .advancedEl, .search-container input[type="text"]) {
    border-color: var(--md-outline-variant);
}

html.md-dark #update-overlay p {
    color: var(--md-on-surface-variant);
}

/* A field that no rule gives a colour (a plain select or number field, a log window): the colour of a field of the
   theme instead of the grey of the browser. Without weight, so that every rule of a page still wins */
:where(html.md-dark) :where(textarea, select, input:not([type=checkbox], [type=radio], [type=range], [type=color], [type=file], [type=submit], [type=button], [type=reset], [type=image])) {
    background-color: var(--md-surface-container-lowest);
    color: var(--md-on-surface);
}

/* The drawings of the wizards (black lines in an <img>) white, the logos of the brands on a white plate: they are made
   for a white page. The plate inside the tile, as wide as the logo was */
html.md-dark img.flexLink[src$=".svg"] {
    filter: invert(1);
}

html.md-dark .providerImageItem .flexImage {
    box-sizing: border-box;
    padding: 10px 14px;
    border-radius: var(--md-shape-md);
    background-color: #FFFFFF;
}

/* ---- Motion -------------------------------------------------------------------------------------------------------- */

/* The motion of the Eniris BMS (bms.eniris.com, front-end/bms): one page fades into the next where the browser can
   (base.html: @view-transition; a browser that cannot just shows the next page), and in every browser a menu or a
   dialog scales in, the drawer slides in over a scrim, a collapsible box unfolds. What opens moves; what closes goes at once, except a
   collapsible box, which folds back. The animations use the individual transform properties (scale, translate), which
   leave the transform of an element alone, and keep no end state (no fill mode): a page still owns the styles of its
   menus and dialogs once they are open. */

@keyframes md-fade-in {
    from { opacity: 0; }
}

@keyframes md-fade-up {
    from { opacity: 0; translate: 0 6px; }
}

@keyframes md-scale-in {
    from { opacity: 0; scale: 0.97; }
}

/* Menus scale in from where they hang: the language menu (it shows when .hidden goes; under the right end of the bar),
   the rich tooltips */
.language-menu:not(.hidden) {
    transform-origin: top right;
    animation: md-scale-in var(--md-duration-menu) var(--md-easing-enter);
}

.help-tip:hover p, .lock-badge:hover .lock-text {
    transform-origin: top left;
    animation: md-scale-in var(--md-duration-menu) var(--md-easing-enter);
}

.lock-badge.lock-text-left:hover .lock-text {
    transform-origin: top right;
}

/* Dialogs scale in over a backdrop that fades in */
dialog[open] {
    animation: md-scale-in var(--md-duration-menu) var(--md-easing-enter);
}

dialog[open]::backdrop {
    animation: md-fade-in var(--md-duration-fade) ease;
}

#update-overlay:not(.hidden) > div {
    animation: md-fade-up var(--md-duration-fade-up) var(--md-easing-enter);
}

/* The drawer slides in from the right, instead of growing from nothing (base.html animates its width over half a second,
   which wraps every item while it opens). Hidden when it is closed, so that its links take no focus */
.sidenav {
    width: 250px;
    translate: 100% 0;
    visibility: hidden;
    box-shadow: var(--md-elevation-3);
    transition: translate var(--md-duration-sheet) var(--md-easing-enter), visibility var(--md-duration-sheet);
}

.sidenav.open {
    translate: none;
    visibility: visible;
}

/* When a page opens from the drawer, the drawer is not part of the bar that stands still (base.html: main-nav): it
   slides away over the next page, as it does when it closes */
.sidenav.open {
    view-transition-name: md-drawer;
}

::view-transition-old(md-drawer) {
    animation-name: md-drawer-away;
}

@keyframes md-drawer-away {
    to {
        translate: 100% 0;
    }
}

/* The theme changed from the open drawer (base.html: mdTheme.toggle, md-theme-change while the page fades into its
   other colours): the drawer stays where it is, with the bar */
html.md-theme-change .sidenav.open {
    view-transition-name: none;
}

/* The scrim under the open drawer. A tap on it lands outside the drawer, which closes it (base.html) */
body::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 9998;              /* under the navigation bar (9999), which holds the drawer */
    background-color: rgba(0, 0, 0, 0.3);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--md-duration-sheet) var(--md-easing-enter);
}

body:has(.sidenav.open)::after {
    opacity: 1;
    pointer-events: auto;
}

/* The wait for the next page (base.js: md-leaving, from the click on a menu item): this page fades out at once (short,
   the interface answers at once) to the grey of the page, and a circle turns in the middle of what is left under the
   bar, as the indeterminate progress indicator of M3: an arc that grows and shrinks while it goes round. The circle
   turns also where the browser asks for less motion (it says that the controller is busy), slower and without the arc
   that grows */
html.md-leaving .maincontent {
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--md-duration) var(--md-easing);
}

.md-wait {
    display: none;
    position: fixed;
    z-index: 9999;              /* over the scrim of the open drawer (9998) */
    left: 50%;
    top: calc(var(--md-nav-height, 0px) + (100vh - var(--md-nav-height, 0px)) / 2);
    translate: -50% -50%;
    width: 48px;
    height: 48px;
    pointer-events: none;       /* a tap on the scrim under it still closes the drawer */
    transition: left var(--md-duration-sheet) var(--md-easing-enter);
}

html.md-leaving .md-wait {
    display: block;
    animation: md-fade-in var(--md-duration-fade-up) var(--md-easing-enter);
}

/* A page opened from the drawer: the circle turns in the middle of what the drawer leaves of the page, and goes to the
   middle of the page when the drawer slides away */
html:has(.sidenav.open) .md-wait {
    left: calc((100% - 250px) / 2);
}

.md-wait svg {
    display: block;
    width: 100%;
    height: 100%;
    animation: md-spin 1.4s linear infinite;
}

.md-wait circle {
    fill: none;
    stroke: var(--md-primary);
    stroke-width: 4;
    stroke-linecap: round;
    stroke-dasharray: 80 200;
    animation: md-arc 1.4s ease-in-out infinite;
}

@keyframes md-spin {
    to { rotate: 360deg; }
}

@keyframes md-arc {
    0% { stroke-dasharray: 1 200; stroke-dashoffset: 0; }
    50% { stroke-dasharray: 90 200; stroke-dashoffset: -35; }
    100% { stroke-dasharray: 90 200; stroke-dashoffset: -124; }
}

@media (prefers-reduced-motion: reduce) {
    .md-wait svg {
        animation-duration: 2.8s;
    }

    .md-wait circle {
        animation: none;
    }
}

/* The sections chosen in the sidebar of a settings page rise into place, like the pages of the BMS */
.settings-section.settings-entering {
    animation: md-fade-up var(--md-duration-fade-up) var(--md-easing-enter);
}

/* A collapsible box unfolds when it is clicked open and folds back when it is closed, in every browser: base.html moves
   its height (Web Animations), with what it holds clipped only while it moves, and what it holds fades in while it
   unfolds (base.html: md-unfolding). A box that is open when the page shows, or that the page opens itself, is just
   there */
details.md-unfolding::details-content {
    animation: md-fade-in var(--md-duration-expand) var(--md-easing-enter);
}

/* A box that is an inline block (.functionbox) hangs from its top: on the baseline, it would hang from its last line of
   text, which is out of sight below its edge while it moves, and leave that much room under it */
details {
    vertical-align: top;
}
