/* Project-wide UI rule: no outlines, including browser focus defaults. */
*, *::before, *::after {
    outline: none !important;
}

/* Shared horizontal spacing for configuration and visualization headers. */
:root {
    --mhome-touch-target-size: 44px;
    --mhome-header-padding-inline: 24px;
    --mhome-header-gap: 18px;
    --mhome-sidebar-group-font-size: 11px;
    --mhome-sidebar-group-gap: 6px;
    --mhome-sidebar-item-indent: 8px;
}
@media (max-width: 760px) {
    :root {
        --mhome-header-padding-inline: 12px;
        --mhome-header-gap: 10px;
    }
}

.appHeader, .visualizationHeader {
    height: 70px;
    min-height: 70px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--mhome-header-gap);
    padding: 0 var(--mhome-header-padding-inline);
    background: #374151;
    color: #fff;
    font: 15px Arial, Helvetica, sans-serif;
    position: sticky;
    top: 0;
    z-index: 900;
    box-shadow: 0 2px 6px rgba(0, 0, 0, .12);
}

.appHeader .headerLeft, .appHeader .headerRight {
    display: flex;
    align-items: center;
}
.appHeader .headerLeft {
    gap: var(--mhome-header-gap);
    min-width: 0;
}
.appHeader .headerRight { gap: 15px; flex-shrink: 0; }
.appHeader #connectionStatus { font-size: 12px; color: #d1d5db; }
@media (max-width: 700px) {
    .appHeader .headerRight { gap: 6px; }
    .appHeader #connectionStatus { display: none; }
}

.headerLeft #pageTitle, .visualizationHeader #projectName {
    display: block;
    margin: 0;
    color: #fff;
    font: 12px Arial, Helvetica, sans-serif;
}

/* Sidebar toggles share the visualization header's button design. */
#sidebarToggleButton, #menuToggle {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 42px;
    width: 42px;
    height: 36px;
    margin: 0;
    padding: 0;
    border: 1px solid #ffffff55;
    border-radius: 7px;
    background: transparent;
    color: inherit;
    font: 15px/18px Arial, Helvetica, sans-serif;
}

/* Keep the branding outside the independently scrollable menu area. */
.sidebar, #navigation, #toolsSidebar { display: flex; flex-direction: column; overflow: hidden; }
.sidebarHeader { flex-shrink: 0; }
.sidebarNav { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.sidebarLogo {
    display: block;
    width: 100%;
    max-width: 200px;
    height: auto;
}

/* Shared editor rows: label / control / validation, repeated on every wrap.
   Subgrid shares track sizes across fields, including multiline labels.
   Controls stay on track 2; validation grows only on track 3. */
:root {
    /* One height for every single-line button, input and dropdown, editor toolbars included.
       Buttons use it as minimum height so wrapped two-line labels grow. */
    --mhome-control-height: 33px;
    --mhome-editor-control-height: var(--mhome-control-height);
    --mhome-control-font-size: 13px;
    --mhome-button-neutral-background: #e5e7eb;
    --mhome-button-neutral-hover: #d1d5db;
    --mhome-button-neutral-text: #222;
    --mhome-table-min-width: 800px;
    --mhome-table-action-width: clamp(160px, 24%, 280px);
    --mhome-table-selection-width: 44px;
    --mhome-table-data-column-min-width: 64px;
    /* Visible area below the sticky app header, minus page and card padding. */
    --mhome-table-max-height: max(280px, calc(100dvh - 140px));
    --mhome-dialog-table-max-height: 60vh;
}
/* Configuration and runtime controls share the compact list-page action scale.
   Authored elements keep their styles; the chrome keeps its own typography. */
body:is(.mhomeConfiguration, .mhomeVisualization) :is(button, input, select, textarea):not(:where(
    [type=checkbox], [type=radio], [type=range], [type=hidden],
    .sidebar *, .appHeader *, .visualizationHeader *, #navigation *, #toolsSidebar *, #operatorView > header *,
    .graphicSurface *, .baseLibraryPreview *, .baseTemplatePreview *, .stylePreview *, .object *
)) {
    font-size: var(--mhome-control-font-size) !important;
}
/* Compact dropdowns share button typography and spacing.
   Widths remain with their form/table layout; multiple-row listboxes keep their geometry. */
body:is(.mhomeConfiguration, .mhomeVisualization) :is(select:not([multiple]):not([size]), select:is([size="0"], [size="1"]):not([multiple])):not(:where(
    .sidebar *, .appHeader *, .visualizationHeader *, #navigation *, #toolsSidebar *, #operatorView > header *,
    .graphicSurface *, .baseLibraryPreview *, .baseTemplatePreview *, .stylePreview *, .object *
)) {
    --mhome-select-font-size: var(--mhome-control-font-size);
    box-sizing: border-box;
    line-height: normal !important;
    height: var(--mhome-control-height) !important;
    min-height: var(--mhome-control-height) !important;
    padding: var(--mhome-button-padding-block) calc(var(--mhome-button-padding-inline) * 3) var(--mhome-button-padding-block) var(--mhome-button-padding-inline) !important;
}
/* Text fields keep their form widths; textarea height stays with its content. */
body:is(.mhomeConfiguration, .mhomeVisualization) :is(input, textarea):not(:where(
    [type=checkbox], [type=radio], [type=range], [type=color], [type=hidden],
    .sidebar *, .appHeader *, .visualizationHeader *, #navigation *, #toolsSidebar *, #operatorView > header *,
    .graphicSurface *, .baseLibraryPreview *, .baseTemplatePreview *, .stylePreview *, .object *
)) {
    box-sizing: border-box;
    line-height: normal !important;
    padding: var(--mhome-button-padding-block) var(--mhome-button-padding-inline) !important;
}
body:is(.mhomeConfiguration, .mhomeVisualization) input:not(:where(
    [type=checkbox], [type=radio], [type=range], [type=hidden],
    .sidebar *, .appHeader *, .visualizationHeader *, #navigation *, #toolsSidebar *, #operatorView > header *,
    .graphicSurface *, .baseLibraryPreview *, .baseTemplatePreview *, .stylePreview *, .object *
)) {
    box-sizing: border-box;
    height: var(--mhome-control-height) !important;
    min-height: var(--mhome-control-height) !important;
}
body:is(.mhomeConfiguration, .mhomeVisualization) button:not(:where(
    .sidebar *, .appHeader *, .visualizationHeader *, #navigation *, #toolsSidebar *, #operatorView > header *,
    .graphicSurface *, .baseLibraryPreview *, .baseTemplatePreview *, .stylePreview *, .object *,
    .mhomeColorTrigger, .mhomeTableName, .tableSort
)) {
    box-sizing: border-box;
    min-height: var(--mhome-control-height);
    padding-block: var(--mhome-button-padding-block);
    line-height: normal;
}
body.mhomeVisualization button:not(:where(
    .sidebar *, .appHeader *, .visualizationHeader *, #navigation *, #toolsSidebar *,
    .graphicSurface *, .object *, .mhomeColorTrigger
)) {
    padding-inline: var(--mhome-button-padding-inline);
}
/* Operator authentication uses the shared action rows outside the dialog shell.
   Keep its existing button appearance; spacing and touch sizes belong here. */
body.mhomeConfiguration :is(#mfaForm, #mfaSetup, #operatorView > header) .mhomeActions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--mhome-space-md);
}
body.mhomeConfiguration :is(#mfaForm, #mfaSetup, #operatorView > header) button {
    min-height: var(--mhome-touch-target-size);
    min-width: var(--mhome-touch-target-size);
    max-width: 100%;
    white-space: normal;
    overflow-wrap: anywhere;
}
body.mhomeConfiguration :is(#mfaForm, #mfaSetup, #operatorView > header) .mhomeActions > button {
    margin: 0;
}
body.mhomeConfiguration :is(#mfaForm, #mfaSetup form) > .mhomeActions {
    margin-block-start: var(--mhome-space-md);
}
body.mhomeConfiguration #mfaSetup {
    display: grid;
    gap: var(--mhome-space-md);
}
/* List defaults also use the shared scale. Inline appearance from the style
   library retains priority, and switches/slider tracks retain their geometry. */
body.mhomeVisualization .object:not(:where(.graphicSurface *)) :is(button:not(.switch), .objectListInput, .objectInput) {
    font-size: var(--mhome-control-font-size);
    line-height: normal;
}
body.mhomeVisualization .object:not(:where(.graphicSurface *)) button:not(:where(.switch, .mhomeColorTrigger)) {
    min-height: var(--mhome-control-height);
    padding: var(--mhome-button-padding-block) var(--mhome-button-padding-inline);
}
body.mhomeVisualization .object:not(:where(.graphicSurface *)) .objectListInput > .objectInput {
    height: calc(var(--mhome-list-control-height, var(--mhome-control-height)) - 2px);
    min-height: calc(var(--mhome-list-control-height, var(--mhome-control-height)) - 2px);
    padding-block: var(--mhome-button-padding-block);
}
body.mhomeVisualization .object:not(:where(.graphicSurface *)) > .objectInput {
    height: var(--mhome-control-height);
    min-height: var(--mhome-control-height);
    padding: var(--mhome-button-padding-block) var(--mhome-button-padding-inline);
}
.mhomeEditorToolbar {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
    column-gap: var(--mhome-space-sm);
    row-gap: var(--mhome-space-xs);
    align-items: stretch;
}
.mhomeEditorToolbar[hidden] { display: none; }
.mhomeEditorToolbar > .mhomeEditorToolbarActions {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--mhome-space-sm);
    min-width: 0;
}
.mhomeEditorToolbar > .mhomeEditorToolbarActions:empty { display: none; }
.mhomeEditorToolbarActions > button {
    flex: 0 1 auto;
    width: auto;
    max-width: 100%;
    min-width: 0;
    min-height: var(--mhome-editor-control-height);
    height: auto;
    margin: 0;
    padding: var(--mhome-button-padding-block) var(--mhome-button-padding-inline);
    font: inherit;
    white-space: normal;
    overflow-wrap: anywhere;
}
.mhomeEditorToolbar > :is(.mhomeEditorToolbarField, .mhomeEditorToolbarSlot) {
    display: grid;
    grid-row: span 3;
    grid-template-rows: subgrid;
    min-width: 0;
    margin: 0;
    gap: var(--mhome-space-xs);
}
.mhomeEditorToolbar .mhomeEditorToolbarLabel {
    grid-row: 1;
    align-self: end;
    overflow-wrap: anywhere;
}
.mhomeEditorToolbarField > :is(input, select),
.mhomeEditorToolbarSlot > * {
    grid-row: 2;
    align-self: start;
}
.mhomeEditorToolbar :is(.mhomeEditorToolbarField, .mhomeEditorToolbarSlot) > :is(button, input:not([type=checkbox]), select, label) {
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    height: var(--mhome-editor-control-height);
    margin: 0;
    font: inherit;
}
/* Buttons and checkbox labels with a wrapped two-line text grow instead of clipping. */
.mhomeEditorToolbar :is(.mhomeEditorToolbarField, .mhomeEditorToolbarSlot) > :is(button, label) {
    min-height: var(--mhome-editor-control-height);
    height: auto;
}
.mhomeEditorToolbarSlot > label {
    display: flex;
    align-items: center;
    gap: var(--mhome-space-xs);
}
.mhomeEditorToolbarSlot input[type=checkbox] { width: auto; margin: 0; }
/* Checkbox labels in the toolbar use the same typography as the field labels. */
.mhomeEditorToolbar .mhomeEditorToolbarSlot > label { font-size: var(--mhome-control-font-size) !important; font-weight: 600 !important; }
.mhomeEditorToolbarField > .mhomeEditorToolbarError {
    grid-row: 3;
    margin: 0;
    overflow-wrap: anywhere;
}
.mhomeEditorToolbar > :is(.mhomeEditorToolbarNote, .mhomeEditorToolbarPanel) {
    grid-column: 1 / -1;
    min-width: 0;
    margin: 0;
}

/* Shared free-editor palette: full labels, content-sized buttons.
   Scrolling belongs to the palette, never to an individual button. */
.graphicPalette {
    min-width: 0;
    box-sizing: border-box;
    padding: var(--mhome-space-sm);
}
.graphicPalette button {
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    min-height: var(--mhome-editor-control-height);
    height: auto;
    max-height: none;
    padding-inline: var(--mhome-space-sm);
    white-space: normal;
    word-break: normal;
    overflow-wrap: anywhere;
    overflow: visible;
    text-overflow: clip;
}
/* Shared direct editing for configuration table names. */
.mhomeTableName {
    width: fit-content;
    max-width: 100%;
    appearance: none;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    padding: 0;
    margin: 0;
    text-align: left;
    cursor: pointer;
    text-decoration: none;
    border-radius: var(--mhome-dialog-button-radius);
}
.mhomeTableName:enabled:hover, .mhomeTableName:enabled:focus-visible {
    background: var(--mhome-button-neutral-hover);
}
.mhomeTableEdit {
    display: grid;
    gap: var(--mhome-space-xs);
    min-width: 0;
}
.mhomeTableEdit > input { box-sizing: border-box; width: 100%; min-width: 0; }
.mhomeTableEdit > .mhomeActions { display: flex; flex-wrap: wrap; gap: var(--mhome-space-xs); }
.mhomeTableEdit > .mhomeActions > button { width: auto; margin: 0; }
.mhomeTableEdit > .error { margin: 0; white-space: normal; }

/* Shared searchable dropdowns in configuration and visualization. Native
   controls retain their layout, values, labels and form validation. */
html.mhomeSearchableSelect body select:not([multiple]):not([size]),
html.mhomeSearchableSelect body select:is([size="0"], [size="1"]):not([multiple]) {
    appearance: none;
    box-sizing: border-box;
    border: 1px solid var(--mhome-dialog-control-border);
    border-radius: var(--mhome-dialog-button-radius);
    padding: var(--mhome-button-padding-block) calc(var(--mhome-button-padding-inline) * 3) var(--mhome-button-padding-block) var(--mhome-button-padding-inline);
    background-color: var(--mhome-button-neutral-background);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='m4 6 4 4 4-4' fill='none' stroke='%23222' stroke-width='1.5'/%3E%3C/svg%3E");
    background-position: right var(--mhome-button-padding-inline) center;
    background-repeat: no-repeat;
    color: var(--mhome-button-neutral-text);
    cursor: pointer;
    text-overflow: ellipsis;
}
html.mhomeSearchableSelect body select:enabled:is(:hover, :focus-visible) {
    background-color: var(--mhome-button-neutral-hover);
}
html.mhomeSearchableSelect body select:disabled {
    opacity: .45;
    cursor: not-allowed;
}
/* Explicit shared component rules also isolate the portal from dialog grids. */
body :is(.mhomeSelectPanel, .mhomeGroupMenu, .mhomePopover) {
    position: fixed;
    inset: auto;
    z-index: 2147483647;
    display: flex;
    flex-direction: column;
    gap: var(--mhome-space-sm);
    box-sizing: border-box;
    margin: 0;
    padding: var(--mhome-space-sm);
    overflow: auto;
    border: 1px solid var(--mhome-dialog-control-border);
    border-radius: var(--mhome-dialog-button-radius);
    background: var(--mhome-dialog-background);
    color: var(--mhome-dialog-text);
    box-shadow: var(--mhome-dialog-shadow);
    font: inherit;
    text-align: left;
}
/* Reusable color trigger: focus uses the foundation's hover surface, never a
   replacement ring. The inner swatch retains the authoritative actual color. */
button.mhomeColorTrigger {
    min-width: var(--mhome-touch-target-size);
    min-height: var(--mhome-touch-target-size);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
button.mhomeColorTrigger:enabled:focus-visible { background: var(--mhome-dialog-button-hover-background); }
.mhomePopover:has(.mhomeColorWheel:focus-visible) { background: var(--mhome-dialog-button-hover-background); }
/* Opt-in shared input styling for application controls outside dialogs. */
body input.mhomeInput,
body .mhomeSelectPanel input.mhomeSelectSearch {
    flex: 0 0 auto;
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    margin: 0;
    padding: var(--mhome-button-padding-block) var(--mhome-button-padding-inline);
    border: 1px solid var(--mhome-dialog-control-border);
    border-radius: var(--mhome-dialog-button-radius);
    background: var(--mhome-dialog-control-background);
    color: var(--mhome-dialog-control-text);
    font: inherit;
}
body .mhomeSelectOptions {
    min-height: 0;
    overflow: auto;
    max-height: 18rem;
    overscroll-behavior: contain;
}
body .mhomeSelectOption {
    padding: var(--mhome-button-padding-block) var(--mhome-button-padding-inline);
    border-radius: var(--mhome-dialog-button-radius);
    color: var(--mhome-dialog-text);
    overflow-wrap: anywhere;
    cursor: pointer;
}
body .mhomeSelectOption[aria-selected="true"] {
    background: var(--mhome-button-neutral-background);
    color: var(--mhome-button-neutral-text);
}
body .mhomeSelectOption[aria-disabled="false"]:is(:hover, .isActive) {
    background: var(--mhome-button-neutral-hover);
    color: var(--mhome-button-neutral-text);
}
body .mhomeSelectOption[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
body .mhomeSelectGroup { padding: var(--mhome-space-sm); font-weight: 600; }
body .mhomeSelectPanel .mhomeSelectStatus { margin: 0; padding-inline: var(--mhome-space-sm); }

/* Configuration page headers: creation actions use primary blue; all other
   actions share the neutral table-button/dropdown palette. Dialogs keep their
   own action hierarchy. Geometry remains with the existing page layout. */
.appPage .pageHeader > button:not(:where(dialog *, .mhomeDialog *)),
.appPage .pageHeader > .pageHeaderActions > button:not(:where(dialog *, .mhomeDialog *)) {
    --page-action-background: var(--mhome-button-neutral-background);
    --page-action-hover: var(--mhome-button-neutral-hover);
    --page-action-active: var(--mhome-button-neutral-hover);
    --page-action-text: var(--mhome-button-neutral-text);
    background: var(--page-action-background);
    color: var(--page-action-text);
    border-color: var(--page-action-background);
}
.appPage .pageHeader > button.primary:not(:where(dialog *, .mhomeDialog *)),
.appPage .pageHeader > .pageHeaderActions > button.primary:not(:where(dialog *, .mhomeDialog *)) {
    --page-action-background: var(--mhome-button-primary);
    --page-action-hover: var(--mhome-button-primary-hover);
    --page-action-active: var(--mhome-button-primary-active);
    --page-action-text: #fff;
}
.appPage .pageHeader > button:enabled:hover:not(:where(dialog *, .mhomeDialog *)),
.appPage .pageHeader > .pageHeaderActions > button:enabled:hover:not(:where(dialog *, .mhomeDialog *)) {
    background: var(--page-action-hover);
    border-color: var(--page-action-hover);
}
.appPage .pageHeader > button:enabled:active:not(:where(dialog *, .mhomeDialog *)),
.appPage .pageHeader > .pageHeaderActions > button:enabled:active:not(:where(dialog *, .mhomeDialog *)) {
    background: var(--page-action-active);
    border-color: var(--page-action-active);
}
.appPage .pageHeader > button:disabled:not(:where(dialog *, .mhomeDialog *)),
.appPage .pageHeader > .pageHeaderActions > button:disabled:not(:where(dialog *, .mhomeDialog *)) {
    opacity: .45;
    cursor: not-allowed;
}


/* Gateway table and page-header foundation, shared by configuration and runtime. */
:where(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) table{width:100%;border-collapse:collapse;font-size:13px}
:where(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) th,:where(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) td{padding:10px;border-bottom:1px solid #e5e7eb;text-align:left;vertical-align:middle}
:where(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) th{background:#f9fafb;white-space:nowrap}
:where(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) tbody tr:hover{background:#f9fafb}
:where(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) .sortable{cursor:pointer;user-select:none}
:where(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) .sortIndicator{font-size:11px;color:#9ca3af}
:where(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) .filterRow th{padding:6px}
:where(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) .filterRow input,:where(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) .filterRow select{min-width:90px;padding:6px;font-size:12px}
.pageHeader{display:flex;justify-content:space-between;align-items:center;gap:20px;min-height:57px;margin-bottom:20px;flex-wrap:wrap}
.pageHeader h2{margin-bottom:5px}
.pageHeader p{margin:0;color:#666}
.pageHeaderActions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-left:auto}
.pageActionButton{width:auto;margin:0;white-space:nowrap}
@media(max-width:700px){
.pageHeader{align-items:flex-start;flex-direction:column}
.pageHeaderActions{width:100%;margin-left:0}
.pageActionButton{width:100%}
}

/* Shared table sizing: text never determines the page width. The wrapper,
   rather than the page, scrolls when the available space is below the minimum. */
.gatewayCard { min-width: 0; width: 100%; }
/* Configuration pages of "Anlagen & Dokumentation": stacked white cards keep one shared gap. */
:is(#page-plant-assets, #page-ga-function-lists, #page-plant-maintenance, #page-current-measurements,
    #page-maintenance-management, #page-project-documentation, #page-asset-catalogs) .card:not(:last-child) {
    margin-block-end: var(--mhome-space-lg, 24px);
}
.gatewayCard > .datapointCopyToolbar { margin-bottom: 1em; }
.gatewayTable .tableSort {
    width: auto;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    font-weight: 700;
    text-align: left;
    cursor: pointer;
}
.gatewayTable .tableSort:hover { color: #2563eb; }
.gatewayTable .filterRow :is(input, select) {
    box-sizing: border-box;
    font-family: inherit;
    border: 1px solid var(--mhome-dialog-control-border);
    border-radius: var(--mhome-dialog-control-radius);
    background: var(--mhome-dialog-control-background);
    color: var(--mhome-dialog-control-text);
}
.gatewayTable .visualizationActions { display: flex; gap: var(--mhome-space-sm); }
.gatewayTable button:not(:where(.tableSort, .mhomeTableName, .mhomeGroupToggle)),
.gatewayCard > .pageHeader button {
    --table-button-background: var(--mhome-button-neutral-background);
    --table-button-hover: var(--mhome-button-neutral-hover);
    --table-button-text: var(--mhome-button-neutral-text);
    width: auto;
    margin: 0;
    padding: var(--mhome-button-padding-block) var(--mhome-button-padding-inline);
    border: 1px solid transparent;
    border-radius: var(--mhome-dialog-button-radius);
    font: inherit;
    background: var(--table-button-background);
    color: var(--table-button-text);
    cursor: pointer;
}
.gatewayTable button:is(.danger, .dangerButton) {
    --table-button-background: var(--mhome-button-danger);
    --table-button-hover: var(--mhome-button-danger-hover);
    --table-button-text: #fff;
}
.gatewayTable button.primary,
.gatewayCard > .pageHeader button.primary {
    --table-button-background: var(--mhome-button-primary);
    --table-button-hover: var(--mhome-button-primary-hover);
    --table-button-text: #fff;
}
.gatewayTable button:not(:where(.tableSort, .mhomeTableName, .mhomeGroupToggle)):enabled:hover,
.gatewayCard > .pageHeader button:enabled:hover { background: var(--table-button-hover); }
.gatewayTable button:disabled { opacity: .45; cursor: not-allowed; }
.gatewayTable .tableClearFilters { padding: var(--mhome-space-xs); font-size: 12px; }
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) {
    box-sizing: border-box;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    overflow-x: auto;
}
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table {
    width: 100%;
    min-width: max(var(--mhome-table-min-width), calc(var(--mhome-table-action-width) + var(--mhome-table-data-columns, 0) * var(--mhome-table-data-column-min-width)));
    table-layout: fixed;
}
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table :is(th, td) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper) > :is(.gatewayTable, .datapointTable, .userTable, .objectBatchTable) > thead > tr:first-child > th:last-child {
    width: var(--mhome-table-action-width);
}
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table > thead > tr:first-child > th.datapointSelection {
    width: var(--mhome-table-selection-width);
}
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table :is(input:not([type=checkbox], [type=radio]), select, textarea) {
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    max-width: 100%;
}
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table :is(.tableSort, .objectSort, .datapointSort, .mhomeTableName) {
    display: block;
    max-width: 100%;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table :is(.visualizationActions, .userActions, .mhomeActions) {
    min-width: 0;
    width: max-content;
    flex-wrap: nowrap;
    white-space: nowrap;
}
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table :is(.visualizationActions, .userActions, .mhomeActions) > button {
    flex: 0 0 auto;
    max-width: none;
    white-space: nowrap;
    overflow-wrap: normal;
}
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table td:has(> .visualizationActions, > .userActions, .mhomeTableEdit) {
    overflow: visible;
}
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table .tableClearFilters {
    min-width: 0;
    max-width: 100%;
    white-space: normal;
    overflow-wrap: anywhere;
}
/* Narrow displays: the action column of the shared management table stays visible at the right edge and
   stacks its buttons; the data columns scroll underneath (a hidden iOS scrollbar no longer hides actions). */
@media (max-width: 760px) {
    .managementTable { --mhome-table-action-width: 132px; }
    .managementTable > thead > tr > th:last-child,
    .managementTable > tbody > tr:not(.mhomeGroupRow) > td:last-child:not(:first-child) {
        position: sticky;
        right: 0;
        z-index: 1;
        box-shadow: -10px 0 8px -8px rgb(15 23 42 / 30%);
    }
    .managementTable > tbody > tr:not(.mhomeGroupRow) > td:last-child:not(:first-child) { background: #fff; }
    .managementTable > tbody > tr:not(.mhomeGroupRow):hover > td:last-child:not(:first-child) { background: #f9fafb; }
    .managementTable > tbody > tr > td:last-child > .visualizationActions { flex-direction: column; align-items: stretch; width: max-content; }
    .managementTable > tbody > tr > td:last-child > .visualizationActions > button { white-space: normal; text-align: center; }
}
/* Form errors and table-wide loading/empty/error messages must stay readable. */
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table td:is([colspan], :has(.mhomeTableEdit), :has(.error)) {
    white-space: normal;
    overflow-wrap: anywhere;
}

/* Column grips are shared table UI, separate from header sorting controls. */
th.mhomeResizableColumn { position: relative; }
th.mhomeResizableColumn > :is(.tableSort, .objectSort, .datapointSort) {
    max-width: calc(100% - 10px);
}
.mhomeColumnResize {
    position: absolute;
    inset-block: 0;
    right: 0;
    width: 10px;
    cursor: col-resize;
    touch-action: none;
    user-select: none;
    z-index: 1;
}
.mhomeColumnResize::after {
    content: '';
    position: absolute;
    inset-block: 20%;
    right: 1px;
    width: 2px;
    background: var(--mhome-dialog-control-border);
}
.mhomeColumnResize:is(:hover, :focus-visible)::after {
    background: var(--mhome-button-primary);
}
.mhomeResizingColumn, .mhomeResizingColumn * {
    cursor: col-resize !important;
    user-select: none !important;
}

/* Configurator groups: shared, organisational list layer of the management
   tables (docs/configurator-groups.md). The accent colour is used sparingly:
   header tint, header edge and a thin edge on the first cell of member rows. */
.mhomeGroupToolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--mhome-space-sm) var(--mhome-space-md);
    margin-bottom: var(--mhome-space-md);
}
.mhomeGroupToolbar[hidden], .mhomeGroupToolbar > [hidden] { display: none; }
.mhomeGroupToolbar > .mhomeActions { display: flex; flex-wrap: wrap; gap: var(--mhome-space-sm); }
.mhomeGroupToolbar > .mhomeActions > button { width: auto; flex: 0 0 auto; margin: 0; }
.mhomeGroupToolbar > .error { flex-basis: 100%; margin: 0; }
.mhomeGroupFilter { display: flex; align-items: center; gap: var(--mhome-space-xs); margin: 0; font-weight: 600; }
.mhomeGroupFilter > select, select.mhomeGroupMove { width: auto; min-width: 12rem; max-width: 100%; margin: 0; font-weight: 400; }
select.mhomeGroupMove[hidden] { display: none; }
.gatewayTable > tbody > tr.mhomeGroupRow > td {
    padding-block: var(--mhome-space-xs);
    border-left: 4px solid var(--mhome-group-accent, #cbd5e1);
    background: color-mix(in srgb, var(--mhome-group-accent, #94a3b8) 7%, #fff);
}
.gatewayTable > tbody > tr.mhomeGroupRow:hover { background: none; }
.mhomeGroupHeader { display: flex; align-items: center; gap: var(--mhome-space-sm); min-width: 0; }
.mhomeGroupHeader > .mhomeActions {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    gap: var(--mhome-space-sm);
    margin-inline-start: auto;
}
.gatewayTable .mhomeGroupToggle {
    display: flex;
    align-items: center;
    gap: var(--mhome-space-sm);
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    margin: 0;
    padding: var(--mhome-space-xs) 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    font-weight: 700;
    text-align: left;
    cursor: pointer;
}
.gatewayTable .mhomeGroupToggle:disabled { opacity: 1; cursor: default; }
.mhomeGroupChevron { flex: 0 0 1em; font-size: 11px; color: #6b7280; }
.mhomeGroupIcon { color: var(--mhome-group-accent, #475569); }
.mhomeGroupName { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mhomeGroupCount { flex: 0 0 auto; white-space: nowrap; font-weight: 400; color: #6b7280; }
.gatewayTable .mhomeGroupMenuButton { flex: 0 0 auto; }
.gatewayTable > tbody > tr.mhomeGroupItem > td:first-child {
    box-shadow: inset 3px 0 0 color-mix(in srgb, var(--mhome-group-accent, transparent) 45%, transparent);
}
.gatewayTable > tbody > tr.mhomeGroupItem[draggable="true"] { cursor: grab; }
.gatewayTable > tbody > tr.mhomeGroupDragging { opacity: .5; }
.gatewayTable > tbody > tr:is(.mhomeGroupDropBefore, .mhomeGroupDropAfter) > td {
    background-image: linear-gradient(var(--mhome-button-primary) 0 0);
    background-repeat: no-repeat;
    background-size: 100% 2px;
}
.gatewayTable > tbody > tr.mhomeGroupDropBefore > td { background-position: top; }
.gatewayTable > tbody > tr.mhomeGroupDropAfter > td { background-position: bottom; }
.gatewayTable > tbody > tr.mhomeGroupDropInto > td { background-color: color-mix(in srgb, var(--mhome-button-primary) 10%, #fff); }
body .mhomeGroupMenu { min-width: 10rem; gap: 0; }
body .mhomeGroupMenu > button {
    display: block;
    width: 100%;
    margin: 0;
    padding: var(--mhome-button-padding-block) var(--mhome-button-padding-inline);
    border: 0;
    border-radius: var(--mhome-dialog-button-radius);
    background: transparent;
    color: var(--mhome-dialog-text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}
body .mhomeGroupMenu > button:is(:hover, :focus-visible) { background: var(--mhome-button-neutral-hover); }
body .mhomeGroupMenu > button.danger { color: var(--mhome-button-danger); }
.mhomeGroupSwatch {
    display: inline-block;
    width: .8em;
    height: .8em;
    border-radius: 50%;
    background: var(--mhome-group-accent);
    vertical-align: middle;
}

/* Opt-in shared table viewport for long management/editing tables. */
/* All configuration tables: column titles and filters stay fixed, rows scroll inside the table. */
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) {
    max-block-size: var(--mhome-table-max-height);
    overflow: auto;
    overscroll-behavior: contain;
}
:where(dialog, .mhomeDialog) :is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) {
    max-block-size: var(--mhome-dialog-table-max-height);
}
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table > thead {
    position: sticky;
    top: 0;
    z-index: 2;
}
/* Collapsed borders do not travel with sticky cells. The tables only draw bottom cell
   borders, so separate borders without spacing look identical and keep the header closed. */
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table {
    border-collapse: separate;
    border-spacing: 0;
}

/* Progressive page/workspace lists grow vertically. Dialog tables retain their
   shared viewport limit, including a progressive table used inside a dialog. */
.gatewayTableWrapper.mhomeTableProgressive:not(:where(dialog *, .mhomeDialog *)) { max-block-size: none; overscroll-behavior-y: auto; }
.mhomeProgressiveStatus { min-width: 0; overflow-wrap: anywhere; }
.mhomeProgressiveList { min-width: 0; max-width: 100%; }
.mhomeTechnicalContent { white-space: pre-wrap; overflow-wrap: anywhere; min-width: 0; }

/* Rounded corners for every management/configuration table, like the visualization tables.
   The wrapper clips the table (overflow) so sticky headers keep the rounded frame. */
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper):not(:where(dialog *, .mhomeDialog *)) {
    border: 1px solid #e0e4e8;
    border-radius: 10px;
}
:is(.gatewayTableWrapper, .datapointTableWrapper, .userTableWrapper, .connectionTableWrapper) > table > tbody > tr:last-child > td { border-bottom: 0; }
