/* ============================================
   ALBACH SPARE PARTS - CLEAN & RESPONSIVE CSS
   Version: 2.0
   ============================================ */

/* ============================================
   CSS VARIABLES
   ============================================ */
:root {
    /* Colors */
    --primary: #198754;
    --primary-dark: #0f5132;
    --primary-light: #e8f5e9;
    --secondary: #6c757d;
    --secondary-dark: #545b62;
    --danger: #dc3545;
    --danger-dark: #c82333;
    --warning: #ffc107;
    --info: #0d6efd;
    --success: #28a745;

    /* Neutrals */
    --white: #ffffff;
    --gray-100: #f8f9fa;
    --gray-200: #e9ecef;
    --gray-300: #dee2e6;
    --gray-400: #ced4da;
    --gray-500: #adb5bd;
    --gray-600: #6c757d;
    --gray-700: #495057;
    --gray-800: #343a40;
    --black: #000000;

    /* Typography */
    --font-family: 'Nunito', Arial, sans-serif;
    --font-mono: 'Consolas', 'Monaco', monospace;
    /* User-adjustable text scale (accessibility). Set at runtime via JS on :root. */
    --font-scale: 1;
    --font-size-xs: calc(11px * var(--font-scale));
    --font-size-sm: calc(12px * var(--font-scale));
    --font-size-base: calc(14px * var(--font-scale));
    --font-size-lg: calc(16px * var(--font-scale));
    --font-size-xl: calc(18px * var(--font-scale));
    --font-size-2xl: calc(20px * var(--font-scale));
    --font-size-3xl: calc(24px * var(--font-scale));

    /* Spacing */
    --spacing-xs: 4px;
    --spacing-sm: 8px;
    --spacing-md: 12px;
    --spacing-lg: 16px;
    --spacing-xl: 20px;
    --spacing-2xl: 24px;

    /* Border Radius */
    --radius-sm: 4px;
    --radius-md: 5px;
    --radius-lg: 8px;

    /* Layout */
    --header-height: 48px;
    --sidebar-width: 280px;
    --sidebar-min: 56px;
    --info-panel-width: 320px;

    /* Transitions */
    --transition-fast: 0.15s ease;
    --transition-base: 0.2s ease;
    --transition-slow: 0.3s ease;
}

/* ============================================
   RESET & BASE
   ============================================ */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html, body {
    width: 100%;
    height: 100%;
    /* overflow: hidden alone is not enough on iOS Safari; the page can
       still pan horizontally when any descendant exceeds the viewport
       width. Locking width + overflow-x at the root absolutely prevents
       sideways scroll on every device. */
    max-width: 100vw;
    overflow: hidden !important;
    overflow-x: hidden !important;
    margin: 0;
    padding: 0;
}

body {
    font-family: var(--font-family);
    font-size: var(--font-size-base);
    background-color: #f5f5f5;
    color: var(--gray-800);
    line-height: 1.5;
}

.Wt-domRoot, body > div {
    margin: 0 !important;
    padding: 0 !important;
    overflow: hidden;
}

/* ============================================
   LOGIN PAGE
   ============================================ */
.login-page {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    padding: var(--spacing-lg);
    background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 50%, var(--primary-dark) 100%);
}

.login-center-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    max-width: 400px;
}

.login-logo {
    max-width: 200px;
    height: auto;
    margin-bottom: 30px;
    filter: brightness(0) invert(1);
}

.login-box {
    background: var(--white);
    padding: 40px var(--spacing-xl);
    border-radius: var(--radius-lg);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
    width: 100%;
    text-align: center;
}

.login-title {
    color: var(--primary);
    margin-bottom: var(--spacing-xl);
}

.login-title h2 {
    margin: 0;
    font-size: var(--font-size-3xl);
    font-weight: 700;
}

.login-input {
    width: 100%;
    padding: var(--spacing-md) var(--spacing-lg);
    margin: var(--spacing-sm) 0;
    border: 2px solid var(--gray-300);
    border-radius: var(--radius-md);
    font-size: var(--font-size-base);
    transition: border-color var(--transition-slow);
}

.login-input:focus {
    border-color: var(--primary);
    outline: none;
}

.login-button {
    width: 100%;
    padding: var(--spacing-md);
    margin-top: var(--spacing-xl);
    background: var(--primary);
    color: var(--white);
    border: none;
    border-radius: var(--radius-md);
    font-size: var(--font-size-lg);
    font-weight: bold;
    cursor: pointer;
    transition: background var(--transition-slow);
}

.login-button:hover {
    background: var(--primary-dark);
}

.login-error {
    color: var(--danger);
    margin-top: var(--spacing-sm);
    font-size: var(--font-size-base);
}

.login-forgot {
    display: block;
    margin-top: var(--spacing-sm);
    text-align: right;
    color: var(--primary);
    font-size: var(--font-size-sm);
    cursor: pointer;
}

.login-forgot:hover {
    text-decoration: underline;
}

.login-reset-msg {
    display: block;
    margin-top: var(--spacing-sm);
    color: var(--primary);
    font-size: var(--font-size-base);
}

.login-account-hint {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 14px;
    padding: 10px 12px;
    border: 1px solid #c9d6e3;
    background: #f3f7fb;
    border-radius: 6px;
    color: #3a4a5a;
    font-size: 0.85em;
    line-height: 1.35;
    text-align: left;
}

.login-account-hint .login-account-hint-icon {
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    vertical-align: baseline;
}

.Wt-dialog.login-request-dialog {
    width: min(480px, 92vw) !important;
    max-width: 92vw !important;
}

/* Dialog internals stay content-width on desktop unless forced. */
.login-request-dialog > .dialog-layout,
.login-request-dialog .titlebar,
.login-request-dialog .body,
.login-request-dialog .footer {
    width: 100% !important;
    box-sizing: border-box !important;
}

.login-request-dialog .footer {
    display: flex !important;
    justify-content: flex-end;
    gap: var(--spacing-sm);
}

.login-request-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.login-request-form input,
.login-request-form select,
.login-request-form textarea {
    width: 100%;
    box-sizing: border-box;
    margin: 0;
}

.login-request-form select {
    padding: var(--spacing-md) var(--spacing-lg);
    border: 2px solid var(--gray-300);
    border-radius: var(--radius-md);
    font-size: var(--font-size-base);
    background: var(--white);
}

.login-request-form select:focus {
    border-color: var(--primary);
    outline: none;
}

.login-request-form textarea {
    min-height: 80px;
    font-family: inherit;
}

.login-request-form .login-request-label {
    margin-bottom: -4px;
    font-size: var(--font-size-sm);
    color: var(--gray-600, #555);
}

.login-footer {
    position: fixed;
    bottom: var(--spacing-xl);
    color: rgba(255, 255, 255, 0.7);
    font-size: var(--font-size-sm);
}

/* ============================================
   NAVIGATION
   ============================================ */
.nav-container {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-sm);
    padding: 10px 15px;
    background: var(--white);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}

.nav-logo-link {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
}

.nav-logo-img {
    height: 40px;
    width: auto;
    display: block;
}

/* Pinned to the logo's baseline edge rather than centred, so the app name sits
   in the same place here and in usermanagementWT. */
.nav-app-title {
    font-weight: 700;
    font-size: 16px;
    color: var(--primary-dark);
    align-self: flex-end;
    line-height: 1.4;
}

/* Slot in the top nav that receives the dropdown/search/cart trio on
   /machine/* (their styling stays the same as in .action-bar). Pushed
   to the right edge by margin-left:auto; wraps on narrow viewports. */
.nav-right-host {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    margin-left: auto;
    flex-wrap: wrap;
    justify-content: flex-end;
    min-width: 0;
}

/* Green strip directly under the white nav. Aligned with the assembly-bar
   inside /machine/* so the two greens read as one continuous bar. */
.action-bar {
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--spacing-md);
    padding: 6px var(--spacing-lg);
    width: 100%;
    box-sizing: border-box;
    /* 48px clears the 32px controls without the dead space a 60px strip left.
       Kept in step with usermanagementWT's green header row. */
    min-height: 48px;
    flex-wrap: wrap;
    row-gap: 6px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.10);
}

.action-bar-spacer {
    flex: 1 1 auto;
    min-width: 0;
}

/* Buttons / dropdowns inside the green action bar get translucent styling
   so they read as part of the bar instead of standalone white chips. */
.action-bar .nav-icon-btn {
    background: rgba(255,255,255,0.15);
    border: 1px solid rgba(255,255,255,0.35);
}

.action-bar .nav-icon-btn:hover {
    background: rgba(255,255,255,0.28);
}

.action-bar .machine-dropdown,
.action-bar .company-switch {
    background: rgba(255,255,255,0.18);
    border: 1px solid rgba(255,255,255,0.4);
    color: var(--white);
}

.action-bar .machine-dropdown option,
.action-bar .company-switch option {
    background: var(--primary);
    color: var(--white);
}

/* Compact the bars on phones so nothing forces horizontal scroll, but
   keep touch targets large enough (>= 40px) and text readable (>= 14px). */
@media (max-width: 768px) {
    .action-bar,
    .nav-container {
        padding-left: 10px;
        padding-right: 10px;
    }
    .nav-right-host,
    .action-bar {
        gap: 8px;
    }
    .nav-right-host .machine-dropdown,
    .nav-right-host .company-switch,
    .action-bar .machine-dropdown,
    .action-bar .company-switch {
        max-width: 200px;
        font-size: calc(14px * var(--font-scale));
        height: 40px;
    }
    .nav-right-host .nav-icon-btn,
    .action-bar .nav-icon-btn {
        width: 40px;
        height: 40px;
        padding: 0;
    }
    .nav-right-host .nav-icon-btn img,
    .action-bar .nav-icon-btn img {
        width: 22px;
        height: 22px;
    }
    .user-dropdown-btn {
        font-size: calc(14px * var(--font-scale));
        padding: 6px 12px;
        height: 40px;
    }
    /* Logo can shrink on very narrow screens but stay tappable. */
    .nav-container .Wt-image,
    .nav-container img,
    .nav-logo-img {
        max-height: 32px;
        height: 32px;
    }
    /* Hide app title in white row when space is tight. */
    .nav-app-title {
        display: none;
    }
    /* User button shrinks so logo + dropdown + user fit on row 1, and
       the right-host (machine selector + search + cart) wraps onto a
       fresh second row with full breathing room. */
    .user-dropdown-btn {
        order: 2;
    }
    .nav-right-host {
        order: 3;
        flex-basis: 100%;
        margin-left: 0;
        justify-content: flex-start;
    }
}

@media (max-width: 480px) {
    .nav-right-host .machine-dropdown,
    .nav-right-host .company-switch,
    .action-bar .machine-dropdown,
    .action-bar .company-switch {
        max-width: 150px;
    }
}

.nav-user {
    color: var(--black);
    margin-right: var(--spacing-lg);
    font-weight: 500;
    display: flex;
    align-items: center;
}

/* Compact solid-green pill for the logout button. Height matches the logo. */
.btn-logout {
    background: var(--primary);
    border: none;
    color: var(--white);
    padding: 0 14px !important;
    border-radius: 6px !important;
    font-size: calc(13px * var(--font-scale)) !important;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: background var(--transition-slow);
    margin-left: 8px;
    height: 32px;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.btn-logout:hover {
    background: var(--primary-dark);
}

/* User dropdown trigger: a green pill (app's signature 135deg gradient)
   holding the full name in white plus a caret. */
.user-dropdown-btn {
    /* !important because Wt writes an inline "display: block" here, which
       collapses the flex row: the 6px gap before the caret disappears and the
       name drops to the baseline instead of centring. usermanagementWT and
       offersystemWT carry the same guard on .um-user-menu-trigger. */
    display: inline-flex !important;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    height: 32px;
    padding: 0 12px;
    margin-left: 8px;
    border-radius: 7px;
    box-sizing: border-box;
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    transition: filter var(--transition-slow);
}

.user-dropdown-btn:hover {
    filter: brightness(1.08);
}

/* Name and caret ignore --font-scale (A-/A+) so the pill keeps the same size
   as in usermanagementWT and AlbachTrac. */
.user-dropdown-name {
    color: var(--white);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 220px;
}

.user-dropdown-caret {
    color: var(--white);
    font-size: 10px;
    line-height: 1;
    flex: 0 0 auto;
}

.secondary-nav {
    background: var(--gray-100);
    border-bottom: 2px solid var(--primary);
}

.machine-dropdown {
    min-width: 200px;
    padding: 5px 10px !important;
    border: 1.5px solid var(--primary) !important;
    border-radius: 6px !important;
    font-size: calc(13px * var(--font-scale)) !important;
    background: var(--white);
    height: 32px;
    box-sizing: border-box;
}

.machine-dropdown:focus {
    outline: none;
    border-color: var(--primary-dark);
}

.nav-icon-btn {
    background: var(--primary);
    color: var(--white);
    border: none;
    padding: 5px 10px !important;
    border-radius: 6px !important;
    font-size: calc(13px * var(--font-scale));
    cursor: pointer;
    margin-left: 6px;
    transition: background var(--transition-slow);
    height: 32px;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Cart button wrapper anchors the badge */
.nav-cart-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
}

/* Badge sits on the wrapper; display/width are forced to beat the generic
   button span rule. */
.nav-cart-wrap > .nav-cart-badge {
    position: absolute;
    top: -5px;
    right: -5px;
    display: block !important;
    width: auto !important;
    min-width: 18px;
    height: 18px;
    box-sizing: border-box;
    padding: 0 4px;
    border-radius: 9px;
    background: #d32f2f;
    color: #fff;
    border: 1.5px solid #fff;
    font-size: 11px;
    font-weight: 700;
    line-height: 15px;
    text-align: center;
    pointer-events: none;
}
.nav-cart-wrap > .nav-cart-badge.is-empty {
    display: none !important;
}

.nav-icon-btn:hover {
    background: var(--primary-dark);
}

.nav-icon-btn img {
    height: 16px;
    width: auto;
    display: block;
    filter: brightness(0) invert(1) contrast(2.2);
}

/* Text-size A-/A+ accessibility buttons live in the footer, right-aligned.
   Translucent-on-green to match the footer bar. */
.footer-a11y {
    position: absolute;
    right: var(--spacing-md);
    top: 50%;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.footer .font-size-btn {
    background: rgba(255,255,255,0.15);
    border: 1px solid rgba(255,255,255,0.4);
    color: var(--white);
    font-weight: 700;
    font-size: calc(14px * var(--font-scale));
    line-height: 1;
    min-width: 30px;
    height: 26px;
    padding: 2px 8px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background var(--transition-base);
}
.footer .font-size-btn:hover {
    background: rgba(255,255,255,0.3);
}

/* Company combo in the top nav — same compact pill as machine-dropdown. */
.company-switch {
    padding: 5px 10px !important;
    border: 1px solid var(--gray-200) !important;
    border-radius: 6px !important;
    font-size: calc(13px * var(--font-scale)) !important;
    background: var(--gray-100);
    height: 32px;
    box-sizing: border-box;
    margin-left: 8px;
}

.search-container {
    display: flex;
    align-items: center;
    margin-left: var(--spacing-sm);
    position: relative;        /* anchor for recent-searches dropdown */
}

.search-input {
    padding: 0 10px !important;
    border: 1.5px solid var(--primary) !important;
    border-radius: 6px !important;
    font-size: calc(13px * var(--font-scale)) !important;
    width: 200px;
    height: 32px !important;
    line-height: 32px !important;
    box-sizing: border-box !important;
    margin: 0 !important;
    vertical-align: middle !important;
}

/* Search panel — small popup anchored near the top-bar search button.
   position: fixed so it floats above the page; right-aligned to where
   the search icon lives. */
/* Positioned under the search button by spPositionPopup (core/anchored_popup_js);
   the fallback values only apply until that runs. */
.search-panel {
    position: fixed;
    top: 64px;
    left: auto;
    right: 16px;
    width: 380px;
    max-width: calc(100vw - 32px);
    z-index: 1000;
    background: #fff;
    border: 1px solid var(--gray-200);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.12),
                0 2px 6px rgba(0,0,0,0.06);
    padding: 10px;
}

.search-panel-inner {
    position: relative;
}

/* Row that holds the text field + close button so they stay aligned on
   one line regardless of viewport width. */
.search-input-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.search-panel .search-input {
    flex: 1 1 auto;
    min-width: 0;
    width: auto !important;
    height: 36px !important;
    font-size: calc(13px * var(--font-scale)) !important;
    padding: 0 12px !important;
    border: 1.5px solid var(--primary) !important;
    border-radius: 6px !important;
    box-sizing: border-box !important;
    margin: 0 !important;
}

.search-close-btn {
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    padding: 0;
    font-size: calc(22px * var(--font-scale));
    line-height: 1;
    background: transparent;
    color: var(--gray-700);
    border: 1.5px solid var(--gray-300);
    border-radius: 6px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.search-close-btn:hover {
    background: var(--gray-100);
    color: var(--gray-900);
    border-color: var(--gray-400);
}

.search-suggestions {
    margin-top: 8px;
    background: #fff;
    border: 1px solid var(--gray-200);
    border-radius: 6px;
    overflow: hidden;
    max-height: 65vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}

.search-header-suggestions {
    max-height: min(420px, 55vh);
}

.search-section-header {
    display: block;
    padding: 8px 14px;
    background: var(--gray-100);
    color: var(--gray-700);
    font-size: calc(11px * var(--font-scale));
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    border-bottom: 1px solid var(--gray-200);
}

/* Two-column variant: title left, "Clear all" right. */
.search-section-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.search-section-title {
    flex: 1 1 auto;
}

.search-clear-all {
    color: var(--primary);
    font-size: calc(11px * var(--font-scale));
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
    cursor: pointer;
    padding: 2px 6px;
    border-radius: 4px;
    transition: background 0.1s;
}

.search-clear-all:hover {
    background: var(--primary);
    color: #fff;
}

/* Recent-search row: label on the left grows; × button anchored right. */
.search-history-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 14px;
    font-size: calc(13px * var(--font-scale));
    color: var(--gray-700);
    border-bottom: 1px solid var(--gray-100);
}

.search-history-item:hover {
    background: var(--primary-light);
}

.search-history-label {
    flex: 1 1 auto;
    cursor: pointer;
    color: var(--gray-700);
}

.search-history-item:hover .search-history-label {
    color: var(--primary-dark);
}

.search-history-del {
    flex: 0 0 auto;
    margin-left: 8px;
    width: 22px;
    height: 22px;
    line-height: 22px;
    text-align: center;
    border-radius: 50%;
    color: var(--gray-500);
    cursor: pointer;
    font-size: calc(16px * var(--font-scale));
    font-weight: 700;
    user-select: none;
    transition: background 0.1s, color 0.1s;
}

.search-history-del:hover {
    background: #f8d7da;
    color: #b02a37;
}

.search-suggestion-item {
    padding: 10px 14px;
    cursor: pointer;
    border-bottom: 1px solid var(--gray-100);
    transition: background 0.1s;
}

.search-suggestion-item:hover {
    background: var(--primary-light);
}

.search-suggestion-label {
    display: block;
    font-size: calc(14px * var(--font-scale));
    font-weight: 500;
    color: var(--gray-700);
}

.search-suggestion-sub {
    display: block;
    font-size: calc(12px * var(--font-scale));
    color: var(--gray-600);
    margin-top: 2px;
}

/* Name slots 2 and 4 under the part label. */
.search-suggestion-details {
    display: block;
    margin-top: 2px;
    color: var(--gray-700);
    font-size: calc(12.5px * var(--font-scale));
    overflow-wrap: anywhere;
}

.suggest-matchedby {
    display: block;
    font-size: calc(11px * var(--font-scale));
    color: #888;
    margin-top: 2px;
}

.search-empty {
    display: block;
    padding: 16px;
    text-align: center;
    color: var(--gray-500);
    font-style: italic;
    font-size: calc(13px * var(--font-scale));
}

.search-see-all {
    display: block;
    padding: 12px 14px;
    background: var(--gray-100);
    color: var(--primary);
    font-weight: 600;
    font-size: calc(13px * var(--font-scale));
    cursor: pointer;
    border-top: 1px solid var(--gray-200);
    text-align: center;
    transition: background 0.1s, color 0.1s;
}

.search-see-all:hover {
    background: var(--primary);
    color: #fff;
}

/* Stays reachable while the suggestions scroll. */
.search-suggestions .search-see-all {
    position: sticky;
    bottom: 0;
}

/* "Did you mean: X?" in the search popup and on the results page. */
.search-did-you-mean {
    display: block;
    padding: 8px 14px;
    color: var(--primary);
    font-size: calc(13px * var(--font-scale));
    cursor: pointer;
}

.search-did-you-mean:hover {
    text-decoration: underline;
}

/* Search tag chip (search box, results page) and tag hint rows. */
.search-tag-chip {
    flex: 0 1 auto;
    display: inline-flex !important;
    align-items: center;
    gap: 6px;
    max-width: 55%;
    min-width: 0;
    padding: 3px 6px 3px 10px;
    background: var(--primary-light);
    border: 1px solid var(--primary);
    border-radius: 14px;
    color: var(--primary-dark);
    font-size: calc(13px * var(--font-scale));
    font-weight: 600;
    white-space: nowrap;
}

.search-tag-off {
    display: none !important;
}

/* Name autocomplete under the search page input. */
.search-page-bar .search-autocomplete {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 60;
    margin-top: 0;
    max-height: 320px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
}

.search-autocomplete .search-tag-hint {
    padding: 7px 12px;
}

/* Set by the browser only (Escape, click outside). */
.search-ac-closed {
    display: none !important;
}

.search-tag-chip-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.search-tag-chip-x {
    flex: 0 0 auto;
    padding: 0 5px;
    border-radius: 50%;
    font-weight: 700;
    line-height: 1.3;
    cursor: pointer;
}

.search-tag-chip-x:hover {
    background: rgba(0, 0, 0, 0.08);
    color: var(--danger);
}

.search-tag-hint {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 9px 14px;
    border-bottom: 1px solid var(--gray-100);
    cursor: pointer;
    transition: background 0.1s;
}

.search-tag-hint:hover {
    background: var(--primary-light);
}

.search-tag-kbd {
    flex: 0 0 auto;
    padding: 0 5px;
    border: 1px solid var(--gray-400);
    border-bottom-width: 2px;
    border-radius: 4px;
    background: #fff;
    color: var(--gray-700);
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: calc(10px * var(--font-scale));
}

.search-tag-kbd-off {
    visibility: hidden;
}

.search-tag-hint-label {
    flex: 0 1 auto;
    min-width: 0;
    color: var(--gray-800);
    font-size: calc(14px * var(--font-scale));
    font-weight: 600;
}

.search-tag-hint-en {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--gray-600);
    font-size: calc(12px * var(--font-scale));
}

.search-tag-hint-count {
    flex: 0 0 auto;
    margin-left: auto;
    color: var(--gray-600);
    font-size: calc(12px * var(--font-scale));
    white-space: nowrap;
}

/* Touch keyboards have no Tab key; the row tap applies the tag. */
@media (hover: none) and (pointer: coarse) {
    .search-tag-kbd {
        display: none;
    }
}

.search-input:focus {
    outline: none;
    border-color: var(--primary-dark);
}

/* Recent-searches dropdown anchored under the search input */
.search-history-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 4px;
    background: #fff;
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-md);
    box-shadow: 0 4px 12px rgba(0,0,0,0.08);
    z-index: 1000;
    max-height: 240px;
    overflow-y: auto;
    padding: 4px 0;
}

.search-history-header {
    display: block;
    padding: 6px 12px;
    color: var(--gray-600);
    font-size: 0.75em;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    border-bottom: 1px solid var(--gray-100);
    margin-bottom: 4px;
}

.search-history-item {
    display: block;
    padding: 6px 12px;
    cursor: pointer;
    font-size: var(--font-size-sm);
    color: var(--gray-700);
}

.search-history-item:hover {
    background: var(--primary-light);
    color: var(--primary-dark);
}

/* ============================================
   WT POPUP & DIALOG
   ============================================ */
.Wt-popupmenu {
    background: var(--white) !important;
    border: 1px solid var(--gray-300) !important;
    border-radius: var(--radius-lg) !important;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15) !important;
    min-width: 160px !important;
    padding: var(--spacing-sm) 0 !important;
    list-style: none !important;
}

.Wt-popupmenu li {
    list-style: none !important;
}

.Wt-popupmenu .Wt-item,
.Wt-popupmenu a {
    display: flex !important;
    align-items: center !important;
    gap: 10px !important;
    padding: var(--spacing-sm) 16px !important;
    font-size: var(--font-size-base) !important;
    color: var(--gray-800) !important;
    text-decoration: none !important;
    cursor: pointer !important;
    transition: background var(--transition-fast) !important;
    background: var(--white) !important;
}

.Wt-popupmenu img {
    width: 18px !important;
    height: 18px !important;
    min-width: 18px !important;
    max-width: 18px !important;
    min-height: 18px !important;
    max-height: 18px !important;
    object-fit: contain !important;
    flex: 0 0 18px !important;
    vertical-align: middle !important;
    padding: 0 !important;
    margin: 0 !important;
}

/* WMenuItem icons render as .Wt-icon background images at the SVG's
   intrinsic size (16-24px); force a uniform box so larger SVGs are not
   clipped by the 16px default from wt.css. */
.Wt-popupmenu .Wt-icon {
    width: 18px !important;
    height: 18px !important;
    padding: 0 !important;
    margin: 0 !important;
    flex: 0 0 18px !important;
    background-size: 18px 18px !important;
    background-position: center !important;
}

.Wt-popupmenu .Wt-item:hover,
.Wt-popupmenu a:hover {
    background: var(--primary-light) !important;
    color: var(--primary) !important;
}

.Wt-popupmenu .Wt-separator {
    border: none !important;
    border-top: 1px solid var(--gray-200) !important;
    margin: var(--spacing-sm) 0 !important;
}

/* User-name dropdown (+ its price submenu): same metrics as the
   usermanagementWT user menu. */
.Wt-popupmenu.user-popup-menu,
.Wt-popupmenu.price-display-menu {
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15) !important;
    min-width: 180px !important;
    padding: 6px 0 !important;
}
.Wt-popupmenu.user-popup-menu .Wt-item,
.Wt-popupmenu.user-popup-menu a,
.Wt-popupmenu.price-display-menu .Wt-item,
.Wt-popupmenu.price-display-menu a {
    padding: 8px 16px !important;
    font-size: calc(13.5px * var(--font-scale)) !important;
    font-weight: 600 !important;
    white-space: nowrap !important;
    transition: background .12s ease !important;
}
.Wt-popupmenu.user-popup-menu .Wt-item:hover,
.Wt-popupmenu.user-popup-menu a:hover,
.Wt-popupmenu.price-display-menu .Wt-item:hover,
.Wt-popupmenu.price-display-menu a:hover {
    color: var(--primary-dark) !important;
}
/* Wt's default theme paints the highlighted row (.active) blue. */
.Wt-popupmenu.user-popup-menu .active,
.Wt-popupmenu.user-popup-menu .active a,
.Wt-popupmenu.price-display-menu .active,
.Wt-popupmenu.price-display-menu .active a {
    background: var(--primary-light) !important;
    color: var(--primary-dark) !important;
    outline: none !important;
}
.Wt-popupmenu.user-popup-menu .Wt-separator,
.Wt-popupmenu.price-display-menu .Wt-separator {
    margin: 6px 0 !important;
    padding: 0 !important;
}
.Wt-popupmenu.user-popup-menu .Wt-submenu-marker,
.Wt-popupmenu.user-popup-menu .submenu {
    margin-left: auto !important;
}

.Wt-dialog {
    background: var(--white) !important;
    border: none !important;
    border-radius: 10px !important;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2) !important;
    min-width: 300px !important;
    overflow: hidden !important;
    /* Snap-open/close — default theme adds CSS transitions that delay
       perceived close by ~200ms. */
    transition: none !important;
    animation: none !important;
}

/* Modal backdrop should also pop instantly. */
.Wt-dialog-bg,
.modal-backdrop {
    transition: none !important;
    animation: none !important;
}

/* Pagination strip under the parts table. */
.edit-parts-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 0;
    border-top: 1px solid var(--gray-300);
    background: var(--white);
}
.edit-parts-pagination button {
    min-width: 36px;
    padding: 4px 10px;
}
.edit-parts-pagination .btn-disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
.edit-parts-pagination-label {
    margin: 0 10px;
    font-weight: 600;
    color: var(--gray-700, #495057);
}

/* Cookie banner — sticky strip at the bottom of the viewport. */
.cookie-banner {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 9999;
    background: #212529;
    color: #f8f9fa;
    padding: 12px 20px;
    font-size: 0.92em;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.2);
}
.cookie-banner-text { flex: 1 1 auto; }
.cookie-banner-link {
    color: #6cc28a;
    text-decoration: underline;
}
.cookie-banner-link:hover { color: #8edaa6; }
.cookie-banner-btn {
    background: #198754;
    color: #fff;
    border: none;
    padding: 8px 18px;
    border-radius: 4px;
    cursor: pointer;
    font-weight: 600;
}
.cookie-banner-btn:hover { background: #157347; }

/* Privacy page typography. */
.privacy-page {
    max-width: 800px;
    margin: 0 auto;
    background: #fff;
    line-height: 1.6;
    color: #212529;
}
.privacy-title { color: var(--primary); margin: 0 0 12px; }
.privacy-section-title { margin-top: 20px; color: #343a40; }
.privacy-section-body, .privacy-intro { color: #495057; }

/* Login page privacy notice (under the form). */
.login-privacy-notice {
    margin-top: 16px;
    font-size: 0.85em;
    color: #6c757d;
    text-align: center;
}
.login-privacy-link {
    color: var(--primary);
    text-decoration: underline;
}

.Wt-dialog .titlebar,
.Wt-dialog .Wt-dialog-title-bar {
    background: var(--primary) !important;
    color: var(--white) !important;
    padding: var(--spacing-lg) var(--spacing-xl) !important;
    font-size: var(--font-size-xl) !important;
    font-weight: bold !important;
    /* Fill the full dialog width (the dialog is stretched to min-width, but the
       title bar otherwise only spans its text → white gap on the right). */
    display: block !important;
    width: 100% !important;
    box-sizing: border-box !important;
}

/* WMessageBox renders as a fit-content flex column of rows (title / body /
   footer). Stretch every row to the full dialog width so a short title doesn't
   leave the title bar shrink-wrapped with a gap on the right. */
.Wt-dialog .dialog-layout { align-items: stretch !important; }
.Wt-dialog .dialog-layout > .Wt-fill-width { width: 100% !important; box-sizing: border-box; }

/* Dialog close (×): enlarge the tiny 13px default Wt sprite globally and
   draw a crisp glyph instead of the bitmap so it scales cleanly. */
.Wt-dialog .closeicon {
    background-image: none !important;
    width: 30px !important;
    height: 30px !important;
    right: var(--spacing-lg) !important;
    /* Sit inside the title bar; 50% centered on the whole dialog and
       overlapped the body content. */
    top: var(--spacing-md) !important;
    font-size: calc(28px * var(--font-scale)) !important;
    line-height: 30px !important;
    text-align: center !important;
    color: var(--white) !important;
    opacity: 0.85;
    cursor: pointer !important;
}

.Wt-dialog .closeicon::before { content: "\00d7"; }

.Wt-dialog .closeicon:hover {
    background-position: right top !important;
    opacity: 1 !important;
}

.Wt-dialog .body,
.Wt-dialog .Wt-dialog-body {
    padding: var(--spacing-xl) !important;
    font-size: var(--font-size-base) !important;
    color: var(--gray-800) !important;
    background: var(--white) !important;
}

.Wt-dialog .Wt-dialog-footer {
    padding: var(--spacing-lg) var(--spacing-xl) !important;
    background: var(--gray-100) !important;
    border-top: 1px solid var(--gray-300) !important;
}

.Wt-dialog .Wt-msgbox-icon { display: none !important; }
.Wt-dialog .Wt-msgbox-text { margin: 0 !important; padding: 0 !important; }

.Wt-dialog .Wt-msgbox-buttons {
    padding: var(--spacing-lg) var(--spacing-xl) !important;
    background: var(--gray-100) !important;
    text-align: right !important;
}

/* WMessageBox footer. The flex layout wraps each row in its own
   `.dialog-layout > .Wt-fill-width`, so `.body.Wt-msgbox-body` and `.footer`
   are not siblings; :has() identifies the message box instead. The page-footer
   `.footer` rule (green rounded bar) also matches it, so reset it to a plain bar. */
.Wt-dialog:has(.Wt-msgbox-body) .footer {
    background: var(--white) !important;
    color: inherit !important;
    margin: 0 !important;
    border-radius: 0 !important;
    border-top: 1px solid var(--gray-200) !important;
    padding: var(--spacing-md) var(--spacing-xl) !important;
    text-align: right !important;
}

/* WMessageBox (Yes/No/Ok) buttons live in the dialog footer in Wt 4, not in a
   .Wt-msgbox-buttons container — style both so message-box buttons aren't raw. */
.Wt-dialog .Wt-msgbox-buttons button,
.Wt-dialog .Wt-dialog-footer button,
.Wt-dialog:has(.Wt-msgbox-body) .footer button {
    background: var(--primary) !important;
    color: var(--white) !important;
    border: none !important;
    padding: var(--spacing-sm) var(--spacing-xl) !important;
    border-radius: var(--radius-md) !important;
    font-size: var(--font-size-base) !important;
    min-width: 100px !important;
    cursor: pointer !important;
    margin-left: var(--spacing-sm) !important;
}

.Wt-dialog .Wt-msgbox-buttons button:hover,
.Wt-dialog .Wt-dialog-footer button:hover,
.Wt-dialog:has(.Wt-msgbox-body) .footer button:hover {
    background: var(--primary-dark) !important;
}

.Wt-dialogcover {
    background: rgba(0, 0, 0, 0.5) !important;
}

/* ============================================
   CONTENT & FOOTER
   ============================================ */
.content-container {
    padding: 0;
    margin: 0;
    background: var(--white);
    min-height: calc(100vh - 200px);
}

.content-container h2 {
    color: var(--primary);
    margin-bottom: var(--spacing-lg);
}

.footer {
    background-color: var(--primary);
    border-radius: var(--radius-md);
    color: var(--white);
    padding: var(--spacing-sm);
    text-align: center;
    margin: var(--spacing-sm) var(--spacing-xl);
    position: relative;
}

.footer a {
    color: var(--white);
    text-decoration: none;
    margin-left: var(--spacing-sm);
}

.footer a:hover {
    text-decoration: underline;
}

/* ============================================
   MACHINE GRID
   ============================================ */
.machine-grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-evenly;
    gap: var(--spacing-xl) 0;
    padding: 0;
}

.machine-card {
    width: 320px;
    min-height: 380px;
    flex-shrink: 0;
    border-radius: 10px;
    overflow: hidden;
    background: var(--white);
    border: 1px solid var(--gray-200);
    box-shadow: 0 1px 3px rgba(0,0,0,0.06),
                0 1px 2px rgba(0,0,0,0.04);
    transition: var(--transition-base);
    display: flex;
    flex-direction: column;
}

/* Bottom spacer inside the flex-column card; replaces the former
   WVBoxLayout addStretch so leftover height collects below the content. */
.machine-card-flex-spacer {
    flex: 1 1 auto;
    min-height: 0;
}

.machine-card:hover {
    border-color: var(--primary);
    box-shadow: 0 6px 16px rgba(25, 135, 84, 0.15),
                0 3px 6px rgba(0,0,0,0.08);
    /* No translateY: a parent has overflow:hidden which would clip the
       top edge of the card while it lifts. Shadow lift is enough. */
}

.machine-card-image-wrap {
    cursor: pointer;
    border-radius: 6px;
    overflow: hidden;
}

.machine-image {
    width: 100%;
    height: auto;
    display: block;
}

.machine-card-name {
    display: block;
    font-weight: 600;
    color: var(--gray-700);
    margin-top: 6px;
}

/* Per-card section buttons (Maintenance / Retrofit Kits — SL only).
   Stacked vertically. !important overrides Wt's default WPushButton skin. */
.machine-card-actions {
    margin-top: 10px;
    border-top: 1px solid var(--gray-200);
    padding-top: 10px;
}

.machine-card .machine-card-btn,
button.machine-card-btn {
    display: block !important;
    width: 100% !important;
    padding: 9px 12px !important;
    border: 1.5px solid var(--primary) !important;
    background: #fff !important;
    color: var(--primary) !important;
    border-radius: 6px !important;
    font-size: calc(14px * var(--font-scale)) !important;
    font-weight: 600 !important;
    cursor: pointer !important;
    text-align: center !important;
    box-shadow: none !important;
    transition: background 0.15s ease, color 0.15s ease,
                transform 0.1s ease, box-shadow 0.15s ease !important;
}

.machine-card .machine-card-btn:hover,
button.machine-card-btn:hover {
    background: var(--primary) !important;
    color: #fff !important;
    box-shadow: 0 2px 6px rgba(25, 135, 84, 0.25) !important;
    transform: translateY(-1px);
}

.machine-card .machine-card-btn:active,
button.machine-card-btn:active {
    transform: translateY(0);
    box-shadow: 0 1px 2px rgba(25, 135, 84, 0.2) !important;
}

/* ============================================
   STATUS MESSAGES
   ============================================ */
.status-text {
    padding: var(--spacing-sm) var(--spacing-lg);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    margin-top: var(--spacing-sm);
    display: block;
}

.status-text.success, .status-success {
    background: #d4edda;
    color: #155724;
    border: 1px solid #c3e6cb;
}

.status-text.error, .status-error {
    background: #f8d7da;
    color: #721c24;
    border: 1px solid #f5c6cb;
}

.status-warning, .status-equal {
    background: #fff3cd;
    color: #856404;
    border: 1px solid #ffeeba;
}

/* ============================================
   BUTTONS - UNIFIED
   ============================================ */
.btn-primary,
.btn-add,
.btn-hotspot,
.btn-management,
.btn-maintenance,
.btn-dialog-ok {
    background: var(--primary) !important;
    color: var(--white) !important;
    border: none !important;
    padding: var(--spacing-sm) var(--spacing-xl) !important;
    border-radius: var(--radius-md) !important;
    font-size: var(--font-size-base) !important;
    cursor: pointer !important;
    transition: background var(--transition-slow) !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    min-width: 100px !important;
}

.btn-primary:hover,
.btn-add:hover,
.btn-hotspot:hover,
.btn-management:hover,
.btn-maintenance:hover,
.btn-dialog-ok:hover {
    background: var(--primary-dark) !important;
}

.btn-secondary,
.btn-cancel,
.btn-back,
.btn-back-orders,
.btn-dialog-cancel {
    background: var(--secondary) !important;
    color: var(--white) !important;
    border: none !important;
    padding: var(--spacing-sm) var(--spacing-xl) !important;
    border-radius: var(--radius-md) !important;
    font-size: var(--font-size-base) !important;
    cursor: pointer !important;
    transition: background var(--transition-slow) !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    min-width: 100px !important;
}

.btn-secondary:hover,
.btn-cancel:hover,
.btn-back:hover,
.btn-back-orders:hover,
.btn-dialog-cancel:hover {
    background: var(--secondary-dark) !important;
}

.btn-danger,
.btn-delete,
.btn-delete-dialog,
.btn-dialog-danger {
    background: var(--danger) !important;
    color: var(--white) !important;
    border: none !important;
    padding: var(--spacing-sm) var(--spacing-lg) !important;
    border-radius: var(--radius-md) !important;
    cursor: pointer !important;
}

.btn-danger:hover,
.btn-delete:hover,
.btn-delete-dialog:hover,
.btn-dialog-danger:hover {
    background: var(--danger-dark) !important;
}

.btn-warning,
.btn-edit {
    background: var(--warning) !important;
    color: var(--gray-800) !important;
    border: none !important;
    padding: var(--spacing-sm) var(--spacing-lg) !important;
    border-radius: var(--radius-md) !important;
    cursor: pointer !important;
}

.btn-warning:hover,
.btn-edit:hover {
    background: #e0a800 !important;
}

.btn-info,
.btn-names {
    background: var(--info) !important;
    color: var(--white) !important;
    border: none !important;
    padding: var(--spacing-sm) var(--spacing-lg) !important;
    border-radius: var(--radius-md) !important;
    cursor: pointer !important;
}

.btn-info:hover,
.btn-names:hover {
    background: #0b5ed7 !important;
}

.btn-success {
    background-color: var(--primary) !important;
    color: var(--white) !important;
    border: none !important;
    padding: var(--spacing-sm) var(--spacing-xl) !important;
    border-radius: var(--radius-md) !important;
    font-size: var(--font-size-base) !important;
    cursor: pointer !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
}

.btn-success:hover {
    background-color: var(--primary-dark) !important;
}

.btn-small {
    padding: var(--spacing-xs) var(--spacing-md) !important;
    font-size: var(--font-size-sm) !important;
}

/* Sort Buttons */
.btn-sort-toggle {
    background: var(--gray-200) !important;
    color: var(--black) !important;
    border: 1px solid var(--gray-400) !important;
    padding: 6px 12px !important;
    border-radius: 6px !important;
    font-weight: 500 !important;
    min-width: 80px;
}

.btn-sort-toggle:hover {
    background: #d6d6d6 !important;
}

.btn-sort-toggle.btn-sort-active {
    background: var(--primary) !important;
    color: var(--white) !important;
    border-color: var(--primary) !important;
}

/* Icon Buttons */
.btn-icon {
    border: none;
    background: transparent !important;
    font-size: var(--font-size-xl);
    cursor: pointer;
    padding: var(--spacing-xs) var(--spacing-sm);
    border-radius: var(--radius-sm);
    transition: opacity var(--transition-fast);
}

.btn-icon:hover { opacity: 0.7; }

.btn-icon-edit { color: var(--info) !important; }
.btn-icon-delete { color: var(--danger) !important; }
.btn-icon-details { color: #6f42c1 !important; }
.btn-icon-info { color: #17a2b8 !important; }
.btn-icon-cart { color: var(--success) !important; }
.btn-icon-zoom { color: var(--info) !important; font-size: var(--font-size-base); }

.btn-icon-danger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-md);
    background: transparent;
    cursor: pointer;
    transition: background-color var(--transition-fast);
    box-shadow: none;
}
.btn-icon-danger:hover {
    background: rgba(220, 53, 69, 0.12);
}
.btn-icon-danger img,
.btn-icon-danger .app-icon {
    width: 18px;
    height: 18px;
    /* red tint the trash svg */
    filter: invert(28%) sepia(64%) saturate(2470%) hue-rotate(335deg) brightness(90%) contrast(94%);
}

.part-detail-icon-btn {
    width: 28px;
    height: 28px;
    padding: 4px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
}

.part-detail-icon-btn img {
    width: 18px !important;
    height: 18px !important;
    display: block !important;
    object-fit: contain !important;
}

/* WT Button Overrides */
.Wt-btn {
    text-align: center !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
}

/* Elements removed for standalone guest sessions. Higher specificity than the
   app-wide `.Wt-btn { display: inline-flex !important }` above, which would
   otherwise override Wt's setHidden (inline display:none, not !important). */
.sp-guest-hidden,
.Wt-btn.sp-guest-hidden,
.action-bar .sp-guest-hidden { display: none !important; }

.Wt-btn br, button br { display: none !important; }

button span, .Wt-WPushButton span {
    text-align: center !important;
    display: block !important;
    width: 100% !important;
}

/* ============================================
   LAYOUT CONTAINERS
   ============================================ */
.actions-container, .action-buttons, .management-container,
.sort-container, .sort-controls, .dialog-buttons,
.dialog-buttons-right, .order-actions, .cart-actions-container,
.cart-quantity-container, .bom-actions {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
}

.dialog-buttons, .dialog-buttons-right {
    justify-content: flex-end;
    padding: var(--spacing-sm) 0;
}

.dialog-footer-split {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
}

.add-btn-container, .assembly-add-container {
    display: flex;
    justify-content: flex-end;
    margin-top: var(--spacing-sm);
}

/* ============================================
   FORM INPUTS
   ============================================ */
.edit-input {
    padding: var(--spacing-sm) var(--spacing-md);
    border: 2px solid var(--gray-300);
    border-radius: var(--radius-md);
    font-size: var(--font-size-base);
    min-width: 250px;
    min-height: 32px;
    background-color: var(--white);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.edit-input:focus {
    border-color: var(--primary);
    outline: none;
    box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);
}

/* Brand-green focus for all edit-dialog fields; replaces the browser default blue ring. */
.edit-dialog input:focus,
.edit-dialog textarea:focus,
.edit-dialog select:focus {
    border-color: var(--primary);
    outline: none;
    box-shadow: 0 0 0 0.2rem rgba(25, 135, 84, 0.25);
}

/* Read-only info fields (border:none) show no ring on focus. */
.edit-dialog input[readonly]:focus,
.edit-dialog select:disabled:focus {
    box-shadow: none;
}

.extra-parent-addrow {
    display: flex;
    gap: var(--spacing-md);
    align-items: center;
    width: 100%;
}
.extra-parent-addrow .edit-input {
    flex: 1 1 auto;
    min-width: 0;
}

/* Child-display tab: one row per automatic sub-assembly with a show/hide checkbox. */
.child-display-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    width: 100%;
}
.child-display-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 100%;
}
.child-display-row {
    display: flex;
    align-items: center;
    width: 100%;
    box-sizing: border-box;
    padding: 8px 10px;
    border: 1px solid #e9ecef;
    border-radius: 6px;
    background: #f8f9fa;
}
.child-display-row input[type="checkbox"] {
    margin-right: 8px;
    flex-shrink: 0;
}
.child-display-row label {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* BOM add row: a single-row table that reuses .bom-edit-table column sizing so
   its Nr / Part / Name / Qty / action cells line up exactly under the list
   above and the two read as one continuous table. */
.bom-addrow-table { margin-top: 4px; }
.bom-addrow-table td { border-bottom: none !important; }
.bom-addrow-table tr:hover { background: transparent; }
/* Add button fills the action column, matching the delete button above it. */
.bom-addrow-table .bom-addrow-add {
    min-width: 0 !important;
    width: 100% !important;
    padding: var(--spacing-sm) 0 !important;
}

.edit-textarea {
    width: 100%;
    min-height: 80px;
    padding: var(--spacing-sm) var(--spacing-lg);
    border: 2px solid var(--gray-300);
    border-radius: var(--radius-md);
    font-size: var(--font-size-base);
    resize: vertical;
}

.edit-textarea:focus {
    border-color: var(--primary);
    outline: none;
}

.edit-current-image {
    border: 2px solid var(--primary);
    border-radius: var(--radius-lg);
    padding: var(--spacing-sm);
}

/* Size to content by default: a form that forgets setWidth() hugs its fields
   instead of ballooning to a fixed viewport width with empty space beside
   left-aligned content. Wide edit-dialogs (import previews, part editor) opt
   back into an explicit width via their own class in the rule below. The
   90vw cap (also enforced !important lower in this file) keeps content on
   screen; the max-height/scroll rule for .edit-dialog lives further down. */
.edit-dialog {
    width: fit-content;
    max-width: 90vw;
}

/* Wide edit-dialogs that intentionally use most of the viewport. They carry
   .edit-dialog for styling but need an explicit width now that .edit-dialog
   hugs content. Kept above the responsive blocks so media/mobile overrides
   (e.g. the <=1024px import-price width, the >=1200px large-dialog width)
   still win at their breakpoints. */
.artikel-import-dialog,
.multi-csv-import-dialog,
.conversion-import-dialog,
.large-dialog,
.import-price-dialog {
    width: 80vw;
}

/* Part links popup: tabbed, so it needs a stable width instead of the
   content-hugging .edit-dialog default. */
.part-detail-dialog {
    width: min(90vw, 760px);
}

/* .edit-dialog sizes the body to its content. Once the root carries an
   explicit width the two disagree, and on a wide screen the body stays narrow
   while the title and footer span the full 760px. Stretch the internals so
   the dialog is one column again. */
.part-detail-dialog > .dialog-layout,
.part-detail-dialog > .Wt-dialog-contents,
.part-detail-dialog > .contents,
.part-detail-dialog .body,
.part-detail-dialog .Wt-dialog-body {
    width: 100% !important;
    box-sizing: border-box !important;
}

/* Part info dialog (search results): the part info panel without its
   sidebar frame. The dialog body is the only scroll container. */
.Wt-dialog.search-part-info-dialog {
    width: min(92vw, 440px);
}

.search-part-info-dialog > .dialog-layout,
.search-part-info-dialog .body {
    width: 100% !important;
    box-sizing: border-box !important;
}

.Wt-dialog.search-part-info-dialog .body {
    padding: 0 !important;
    max-height: 75vh !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
}

.part-info-embedded {
    background: var(--white);
}

.part-info-embedded .part-info-content {
    overflow: visible;
}

/* Part price export: fixed-width form instead of the content-hugging
   .edit-dialog default; internals stretch to the root width. */
.part-price-export-dialog {
    width: min(90vw, 440px);
}

.part-price-export-dialog > .dialog-layout,
.part-price-export-dialog .body {
    width: 100% !important;
    box-sizing: border-box !important;
}

.part-price-export .export-dialog-section {
    margin-bottom: var(--spacing-lg);
}

.part-price-export .ppe-combo {
    display: block;
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
}

.part-price-export .ppe-empty {
    display: block;
    color: var(--gray-600);
    font-size: var(--font-size-sm);
}

.part-price-export-dialog .dialog-buttons {
    flex-wrap: wrap;
    margin-top: var(--spacing-sm);
    padding: var(--spacing-md) 0 0;
    border-top: 1px solid var(--gray-200);
}

.part-detail-dialog .part-detail-tab-page {
    padding: 10px 4px;
    min-height: 220px;
}

/* "Used in assemblies" tab. */
.part-detail-usage-count {
    display: block;
    margin-bottom: 8px;
    color: #6c757d;
    font-size: var(--font-size-sm);
}

.part-detail-usage-empty {
    color: #6c757d;
    font-style: italic;
}

.part-detail-usage-table {
    width: 100%;
    border-collapse: collapse;
}

.part-detail-usage-table th,
.part-detail-usage-table td {
    padding: 5px 8px;
    border-bottom: 1px solid #e9ecef;
    text-align: left;
    vertical-align: top;
}

.part-detail-usage-table td:last-child {
    color: #6c757d;
}

.part-detail-usage-partnr {
    color: #495057;
    font-weight: 600;
    white-space: nowrap;
}

/* Machine grouping heading; only rendered when the part spans machines. */
.part-detail-usage-machine td {
    background: #f0f4f8;
    font-weight: 600;
    color: #495057;
    border-bottom: 1px solid #dee2e6;
}

.part-detail-usage-code {
    color: var(--primary);
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
}

.part-detail-usage-row-current td {
    background: #fff8e1;
}

/* Document tabs (handbook / change management): one card per document. */
.part-detail-docs-count {
    display: block;
    margin-bottom: 8px;
    color: #6c757d;
    font-size: var(--font-size-sm);
}

.part-detail-docs-empty {
    color: #6c757d;
    font-style: italic;
}

.part-detail-doc {
    padding: 8px 0;
    border-bottom: 1px solid #e9ecef;
}

.part-detail-doc-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.part-detail-doc-title {
    color: var(--primary);
    font-weight: 600;
    text-decoration: none;
    /* Long wiki titles wrap instead of widening the dialog. */
    overflow-wrap: anywhere;
}

.part-detail-doc-title:hover { text-decoration: underline; }

.part-detail-doc-id {
    flex: 0 0 auto;
    color: #adb5bd;
    font-size: var(--font-size-sm);
}

.part-detail-doc-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 4px;
}

.part-detail-doc-meta > * {
    padding: 1px 7px;
    border-radius: 10px;
    font-size: 0.75em;
    font-weight: 600;
    white-space: nowrap;
}

.part-detail-doc-rel    { background: #dbeafe; color: #1e40af; }
.part-detail-doc-status { background: #ede9fe; color: #5b21b6; }
.part-detail-doc-chip   { background: #f1f3f5; color: #495057; }
.part-detail-doc-date   { background: transparent; color: #adb5bd; font-weight: 400; }

.part-detail-usage-current {
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 10px;
    background: #ffe08a;
    color: #6b4d00;
    font-size: 0.75em;
    font-weight: 600;
    text-decoration: none;
}

/* Add-assembly dialog gets tall in "Create new group" mode (18-language list).
   Cap the body and scroll internally so the footer (Save/Cancel) stays
   reachable. Targets the body only; the footer is a separate pinned element. */
.add-group-dialog .Wt-dialog-body {
    max-height: 68vh;
    overflow-y: auto;
}

/* Assembly export drag & drop zone */
.asm-dropzone {
    border: 2px dashed var(--gray-300, #ced4da);
    border-radius: 10px;
    padding: 30px 20px;
    text-align: center;
    color: #6c757d;
    background: #f8f9fa;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, color .15s ease, transform .1s ease;
}
.asm-dropzone:hover {
    border-color: #198754;
    color: #198754;
    background: #f1f8f4;
}
.asm-dropzone.Wt-dropzone-hover,
.asm-dropzone.Wt-dropzone-indication {
    border-color: #198754;
    background: #e8f5ee;
    color: #198754;
    transform: scale(1.01);
}
/* Drop-zone children must not capture drag events: otherwise dragenter/
   dragleave flickers between the icon/text and the zone, and the file drop
   is detected unreliably. All drag/pointer events go to the zone itself. */
.asm-dropzone * { pointer-events: none; }
.asm-dropzone-icon  { display:block; width: 30px; height: 30px; margin: 0 auto 10px; opacity: .7; }
.asm-dropzone-title { display:block; font-weight: 600; font-size: 1.05em; }
.asm-dropzone-hint  { display:block; font-size: .8em; margin-top: 6px; letter-spacing: .06em; opacity: .7; text-transform: uppercase; }
.asm-upload-status  { margin-top: 12px; }
.asm-upload-row     { display:block; padding: 3px 0; font-size: .88em; }

/* Per-file-type cards (separate SVG/CSV/PNG/GLTF drop zones) */
.asm-file-card {
    border: 1px solid var(--gray-300, #dee2e6);
    border-radius: 8px;
    padding: 12px 14px;
    background: #fff;
}
.asm-file-head { display:flex; align-items:center; gap:10px; margin-bottom: 6px; }
.asm-file-title { font-weight: 700; font-size: 1em; color: #343a40; }
.asm-file-badge { padding: 1px 9px; border-radius: 10px; font-size: .72em; font-weight: 700; }
.asm-file-badge-on  { background: #d1e7dd; color: #0f5132; }
.asm-file-badge-off { background: #f8d7da; color: #842029; }
.asm-file-current { display:block; font-size: .85em; color: #6c757d; word-break: break-all; }
.asm-file-current-row { display:flex; align-items:center; gap:8px; margin-bottom: 8px; }
.asm-file-current-row .asm-file-current { flex:1; }
.asm-dropzone-sm { padding: 14px 12px; border-radius: 8px; }
.asm-dropzone-sm .asm-dropzone-icon { width: 22px; height: 22px; margin-bottom: 4px; }

/* ── 3D viewer popup: viewport-relative, capped for very large/small screens ── */
.threejs-viewer-popup {
    max-width: 1500px;
    max-height: 94vh;
    min-width: 300px;
}
.threejs-viewer-wrap { min-height: 240px; }
/* Portrait / narrow screens: use nearly the full width and height. */
@media (max-width: 900px) {
    .threejs-viewer-popup { max-width: 96vw; }
}

@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
    body div.Wt-dialog.threejs-viewer-popup,
    .Wt-dialog.threejs-viewer-popup,
    .threejs-viewer-popup {
        width: 96vw !important;
        min-width: 0 !important;
        max-width: 96vw !important;
        height: 88dvh !important;
        min-height: 420px !important;
        max-height: 92dvh !important;
    }

    .threejs-viewer-popup .Wt-dialog-contents,
    .threejs-viewer-popup .contents,
    .threejs-viewer-popup .body,
    .threejs-viewer-popup .Wt-dialog-body {
        min-height: 0 !important;
        height: 100% !important;
        overflow: hidden !important;
    }

    .threejs-viewer-popup .threejs-viewer-wrap {
        min-height: 300px !important;
        height: calc(88dvh - 120px) !important;
    }
}

/* Send-order is a long form. Keep one scroll owner (the dialog body) and keep
   the complete card inside the viewport on desktop and narrow layouts alike. */
body div.Wt-dialog.send-order-dialog,
.Wt-dialog.send-order-dialog {
    position: fixed !important;
    top: 50% !important;
    left: 50% !important;
    right: auto !important;
    bottom: auto !important;
    width: min(96vw, 1040px) !important;
    min-width: 0 !important;
    max-width: 96vw !important;
    height: min(90dvh, 780px) !important;
    max-height: min(90dvh, 780px) !important;
    margin: 0 !important;
    transform: translate(-50%, -50%) !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
}
.Wt-dialog.send-order-dialog > .Wt-dialog-contents,
.Wt-dialog.send-order-dialog > .contents {
    display: flex !important;
    flex: 1 1 auto !important;
    flex-direction: column !important;
    min-height: 0 !important;
    max-height: none !important;
    overflow: hidden !important;
}
.Wt-dialog.send-order-dialog .body,
.Wt-dialog.send-order-dialog .Wt-dialog-body {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    max-height: none !important;
    overflow-x: hidden !important;
    overflow-y: hidden !important;
    padding: 0 !important;
}
.Wt-dialog.send-order-dialog .cart-dialog-content {
    width: 100% !important;
    height: 100% !important;
    min-height: 0 !important;
    max-height: 100% !important;
    box-sizing: border-box !important;
    overflow-x: hidden !important;
    overflow-y: auto !important;
    padding: 18px !important;
}
.Wt-dialog.send-order-dialog .send-order-products-column .checkout-items {
    max-height: calc(min(90dvh, 780px) - 155px) !important;
}
@media only screen and (max-width: 860px) {
    body div.Wt-dialog.send-order-dialog,
    .Wt-dialog.send-order-dialog {
        width: min(94vw, 620px) !important;
        max-width: 94vw !important;
        height: 88dvh !important;
        max-height: 88dvh !important;
    }
    .Wt-dialog.send-order-dialog .send-order-products-column .checkout-items {
        max-height: min(34dvh, 260px) !important;
    }
}

/* Responsive checkout layout: columns remain side-by-side only while each can
   keep a usable form width; auto-fit stacks them naturally on narrow tablets. */
body div.Wt-dialog.send-order-dialog,
.Wt-dialog.send-order-dialog {
    width: min(96vw, 1040px) !important;
    max-width: 96vw !important;
    height: min(90dvh, 780px) !important;
    max-height: min(90dvh, 780px) !important;
}
.Wt-dialog.send-order-dialog .body,
.Wt-dialog.send-order-dialog .Wt-dialog-body {
    overflow: hidden !important;
}
.Wt-dialog.send-order-dialog .cart-dialog-content {
    height: 100% !important;
    max-height: 100% !important;
    min-height: 0 !important;
    overflow-x: hidden !important;
    overflow-y: auto !important;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}
.send-order-columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 390px), 1fr));
    align-items: start;
    gap: 24px;
    margin-top: 14px;
}
.send-order-products-column,
.send-order-details-column {
    min-width: 0;
}
.send-order-products-column {
    position: sticky;
    top: 0;
}
.send-order-products-column .checkout-items {
    max-height: calc(min(90dvh, 780px) - 155px) !important;
    overflow-y: auto !important;
    scrollbar-gutter: stable;
}
.send-order-details-column .dialog-section-title:first-child {
    margin-top: 0;
}

@media only screen and (max-width: 860px) {
    body div.Wt-dialog.send-order-dialog,
    .Wt-dialog.send-order-dialog {
        width: min(94vw, 620px) !important;
        max-width: 94vw !important;
        height: 88dvh !important;
        max-height: 88dvh !important;
    }
    .send-order-columns { grid-template-columns: 1fr; gap: 18px; }
    .send-order-products-column { position: static; }
    .send-order-products-column .checkout-items {
        max-height: min(34dvh, 260px) !important;
    }
}

/* ── Multi-PNG list ── */
.asm-png-list { display:flex; flex-direction:column; gap:6px; margin-bottom: 8px; }
.asm-png-row { display:flex; align-items:center; gap:10px; padding:4px 6px; border:1px solid var(--gray-300, #e9ecef); border-radius:6px; background:#fff; }
.asm-png-thumb { width:40px; height:40px; object-fit:contain; border:1px solid #e9ecef; border-radius:4px; background:#f8f9fa; }
.asm-png-name { flex:1; font-size:.85em; color:#495057; word-break:break-all; }

/* ── Restorable versions list ── */
.asm-versions { margin-bottom: 16px; }
.asm-versions-head { display:block; font-weight:700; font-size:1em; color:#343a40; margin-bottom:8px; }
.asm-version-row { display:flex; align-items:center; gap:10px; padding:8px 10px; margin-bottom:4px; border:1px solid var(--gray-300, #e9ecef); border-radius:6px; background:#fff; }
.asm-version-meta { flex:1; font-size:.85em; color:#495057; }

/* ── App SVG icons (replace emoji; identical on every platform) ── */
/* Inline button spinner (e.g. Translate while DeepL is working) */
.btn-spinner { position: relative; min-width: 30px; color: transparent !important; pointer-events: none; }
.btn-spinner::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: 12px; height: 12px; margin: -6px 0 0 -6px;
    border: 2px solid rgba(25, 135, 84, .25); border-top-color: #198754;
    border-radius: 50%; animation: btn-spin .6s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }

/* Ajax loading indicator. Overrides the inline rules Wt adds for its own
   red default box, hence the !important flags. The fade-in delay keeps
   short requests from flashing the badge. */
div.Wt-loading {
    position: fixed !important;
    top: 14px !important;
    right: 14px !important;
    left: auto !important;
    z-index: 10000;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 14px 7px 11px;
    border-radius: 999px;
    background: var(--primary, #198754) !important;
    color: #fff !important;
    font-family: var(--font-family, 'Nunito', Arial, sans-serif) !important;
    font-size: var(--font-size-sm, 12px) !important;
    font-weight: 700;
    letter-spacing: .2px;
    box-shadow: 0 4px 14px rgba(15, 81, 50, .35);
    pointer-events: none;
    opacity: 0;
    animation: sp-loading-in .18s ease-out .25s forwards;
}
div.Wt-loading::before {
    content: ""; flex: 0 0 13px; width: 13px; height: 13px;
    border: 2px solid rgba(255, 255, 255, .35); border-top-color: #fff;
    border-radius: 50%; animation: btn-spin .6s linear infinite;
}
@keyframes sp-loading-in {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    div.Wt-loading { animation: none; opacity: 1; }
    div.Wt-loading::before { animation-duration: 1.8s; }
}
@media (max-width: 768px) {
    div.Wt-loading { top: 10px !important; right: 10px !important; }
}

/* Dialog fade-in (note prompt and other modal dialogs). */
.dialog-fade .Wt-dialog,
.dialog-fade.Wt-dialog { animation: dialog-fade-in .16s ease-out; }
@keyframes dialog-fade-in {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Busy indicator shown on a drop zone while an upload is processed. */
.drop-busy { position: relative; pointer-events: none; opacity: .6; }
.drop-busy::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: 18px; height: 18px; margin: -9px 0 0 -9px;
    border: 2px solid rgba(25, 135, 84, .25); border-top-color: #198754;
    border-radius: 50%; animation: btn-spin .6s linear infinite;
}

/* Inline status line inside dialogs (e.g. send-report result). */
.status-text { font-size: calc(13px * var(--font-scale)); margin-top: 2px; }
.status-text.error { color: #dc3545; }
.status-text.success { color: #198754; }

/* Prominent status banner at the top of the send-report (MantisHub) dialog.
   Larger and boxed so send errors are immediately visible. */
.mantis-status {
    display: block;
    font-size: calc(16px * var(--font-scale));
    font-weight: 600;
    line-height: 1.4;
    padding: 12px 16px;
    margin: 4px 0 12px;
    border-radius: 8px;
    border: 1px solid transparent;
}
.mantis-status.error {
    color: #721c24;
    background: #f8d7da;
    border-color: #f1aeb5;
}
.mantis-status.success {
    color: #0f5132;
    background: #d1e7dd;
    border-color: #a3cfbb;
}

/* Change-history list (editor tab + part sidebar). */
.history-list { display: flex; flex-direction: column; gap: 8px; }
.history-empty { color: #6c757d; font-style: italic; font-size: 0.9em; }
.history-item { padding: 8px 10px; border: 1px solid #e9ecef; border-radius: 6px; background: #f8f9fa; }
.history-item-click { cursor: pointer; transition: background .12s; }
.history-item-click:hover { background: #e9ecef; border-color: #ced4da; }
.history-item-meta { font-size: calc(12px * var(--font-scale)); color: #495057; }
.history-item-detail { display: block; margin-top: 3px; font-size: calc(13px * var(--font-scale)); color: #212529; }
.history-item-note { display: block; margin-top: 4px; font-size: calc(13px * var(--font-scale)); color: #6c757d; font-style: italic; white-space: pre-wrap; }
.history-item-kinds { display: inline-block; margin-top: 4px; padding: 1px 7px; font-size: calc(11px * var(--font-scale)); font-weight: 600;
    letter-spacing: .3px; color: #198754; background: #d1e7dd; border-radius: 10px; }
.history-item-link { display: inline-block; margin-top: 4px; margin-right: 8px; font-size: calc(12px * var(--font-scale)); color: #0d6efd; }
.part-info-history-title { display: block; margin: 10px 0 6px; font-weight: 600; font-size: 0.9em; color: #495057; }

/* Per-entity audit/activity table (editor tab). */
.activity-table { width: 100%; font-size: calc(13px * var(--font-scale)); }
.activity-table th, .activity-table td { padding: 5px 8px; border-bottom: 1px solid #eef0f2; text-align: left; vertical-align: top; }
.activity-action { font-weight: 600; color: #495057; }

.app-icon    { width: 1.05em; height: 1.05em; vertical-align: -0.16em; }
.app-icon-sm { width: 0.9em;  height: 0.9em;  vertical-align: -0.12em; }
.app-icon-lg { width: 1.4em;  height: 1.4em;  vertical-align: -0.28em; }

/* Default size for any icon Wt renders into a push button (setIcon -> <img>).
   Sizes icons by context rather than the SVG's intrinsic width/height; more
   specific button rules (nav-icon-btn, part-detail-icon-btn) still win. */
.Wt-btn img {
    width: 22px;
    height: 22px;
    object-fit: contain;
    vertical-align: middle;
}

/* Icon + text buttons. wt.css `.Wt-btn.with-label img { padding-right: 10px }`
   plus border-box shrinks the glyph by 10px; the spacing becomes a margin.
   :where() keeps specificity at .Wt-btn img so later per-button rules win.
   16px + 6px keeps the old 22px footprint. */
.Wt-btn.with-label img {
    padding-right: 0 !important;
}

.Wt-btn:where(.with-label) img {
    width: 16px;
    margin-right: 6px;
}

/* Icons rendered inside colored buttons (Wt setIcon -> <img>) appear white. */
.btn-primary img, .btn-danger img, .btn-add img,
.part-info-edit-btn img,
.pdf-header-close img,
.btn-white-icon img,
.btn-primary .app-icon, .btn-danger .app-icon {
    filter: brightness(0) invert(1);
}

/* Multi-filter checklist panel */
.asm-filter-panel {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 22px;
    padding: 10px 14px;
    margin: 6px 0;
    border: 1px solid var(--gray-300, #dee2e6);
    border-radius: 8px;
    background: #f8f9fa;
}
.asm-filter-cb { font-size: .9em; color: #343a40; }

/* Bulk re-parent action bar + row select checkbox */
.asm-bulk-bar {
    display: flex;
    align-items: center;
    padding: 4px 8px;
    margin: 4px 0;
    border: 1px solid var(--primary, #0d6efd);
    border-radius: 8px;
    background: #eef4ff;
    font-size: .9em;
    color: #343a40;
}
.asm-select-cb { margin-right: 6px; vertical-align: middle; }

/* Expandable version group header row */
.asm-version-group-row { background: #f1f3f5; }
.asm-version-group-head { cursor: pointer; color: var(--primary, #0d6efd); }
.asm-version-group-head:hover { text-decoration: underline; }
.asm-version-group-name { cursor: pointer; color: #495057; margin-left: 8px; }

/* Sort-mode drag-drop reordering of sibling groups. Rows are drag sources
   (the whole tile grabs); the dashed full-width gap lines between groups are
   the drop targets (insertion point). */
.asm-group-draggable { cursor: grab; display: flex; align-items: center; gap: 6px; width: 100%; min-height: 26px; }
.asm-group-draggable:active { cursor: grabbing; }
/* Invisible drag image (used via setDraggable isDragWidgetOnly): the green
   insertion line is the only drop cue, so no ghost is shown. */
.asm-drag-ghost { width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.asm-drop-gap { height: 16px; position: relative; }
.asm-drop-gap::before {
    content: "";
    position: absolute; left: 0; right: 0; top: 50%; margin-top: -1px;
    border-top: 2px dashed #b6cfc0;
}
.asm-drop-gap.asm-drop-gap-hover { background: rgba(25, 135, 84, .10); border-radius: 4px; }
.asm-drop-gap.asm-drop-gap-hover::before { border-top: 4px solid #198754; margin-top: -2px; }

/* ============================================
   TABLES - BASE STYLES
   ============================================ */
.edit-assembly-table, .bom-edit-table, .machine-table,
.assembly-table, .edit-parts-table, .edit-price-table,
.bom-table, .order-table, .cart-items-table,
.search-table, .hotspot-parts-table, .import-preview-table,
.csv-table, .info-table, .part-info-table, .order-info-table,
.order-items-table {
    width: 100%;
    border-collapse: collapse;
}

.edit-assembly-table th, .bom-edit-table th,
.machine-table th, .bom-table th {
    background: var(--primary);
    color: var(--white);
    font-weight: 600;
    text-align: left;
}

.edit-assembly-table th, .edit-assembly-table td,
.bom-edit-table th, .bom-edit-table td,
.machine-table th, .machine-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    border-bottom: 1px solid var(--gray-300);
    vertical-align: middle;
}

.edit-assembly-table tr:hover,
.bom-edit-table tr:hover,
.machine-table tr:hover {
    background: var(--gray-100);
}

/* machine-table: let text columns absorb width and keep the actions cell
   (Edit/Delete) from ever being clipped, regardless of column count. */
.machine-table td:has(> .actions-container) { white-space: nowrap; width: 1%; }
.machine-table .actions-container { flex-wrap: nowrap; }
/* Keeps a wide table inside its container instead of overflowing.
   `anywhere` lets a column shrink below its longest word; max-width caps the
   greedy text columns; min-width is the floor that stops short values (ids,
   counts) from being squeezed into a two-character stack. */
.machine-table td {
    max-width: 360px;
    /* box-sizing is border-box here, so the cell padding has to be added on
       top of the text floor or it eats into it. */
    min-width: calc(4ch + 2 * var(--spacing-md));
    overflow-wrap: anywhere;
}

/* BOM edit table: fit within the dialog (no horizontal scroll). Fixed layout
   with narrow Nr/Qty/action columns; the part-number and name inputs shrink to
   share the remaining width instead of forcing their 250px min-width. */
.bom-edit-table { table-layout: fixed; }
.bom-edit-table th:nth-child(1), .bom-edit-table td:nth-child(1),
.bom-edit-table th:nth-child(4), .bom-edit-table td:nth-child(4) { width: 72px; }
.bom-edit-table th:nth-child(5), .bom-edit-table td:nth-child(5) { width: 116px; text-align: center; }
.bom-edit-table th:nth-child(6), .bom-edit-table td:nth-child(6) { width: 56px; text-align: center; }
.bom-edit-table .edit-input {
    min-width: 0;
    width: 100%;
    box-sizing: border-box;
}

/* Which detail layer applies to a BOM row in this assembly. The label carries
   the state; colour only reinforces it, so it stays readable without colour. */
.bom-detail-badge {
    display: inline-block;
    max-width: 100%;
    padding: 1px 8px;
    border-radius: 10px;
    font-size: var(--font-size-sm);
    line-height: 1.6;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    box-sizing: border-box;
}
.bom-detail-badge--none       { background: rgba(107, 114, 128, 0.12); color: #5a6472; }
.bom-detail-badge--global     { background: rgba(40, 167, 69, 0.14);   color: #1e7e34; }
.bom-detail-badge--assembly   { background: rgba(184, 134, 11, 0.16);  color: #8a6100; }
.bom-detail-badge--suppressed { background: rgba(220, 53, 69, 0.12);   color: #b02a37; }

/* Selected rows */
.edit-assembly-table tr.Wt-selected td,
.edit-assembly-table tr.selected td,
.assembly-table tr.Wt-selected td,
.assembly-table tr.selected td {
    background-color: #e0f2e9 !important;
    font-weight: 600;
}

.assembly-table-container {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
    border: 1px solid #e0e0e0;
    border-radius: 6px;
    background: var(--white);
}

/* Assembly Table Indentation */
.assembly-table td.assembly-level-0 { padding-left: 4px; }
.assembly-table td.assembly-level-1 { padding-left: 20px; }
.assembly-table td.assembly-level-2 { padding-left: 36px; }
.assembly-table td.assembly-level-3 { padding-left: 52px; }

.assembly-name-root { font-weight: 600; }
.assembly-name-child { font-weight: 400; }

/* ============================================
   EDIT TABS
   ============================================ */
.edit-tabs {
    width: 100%;
    margin-top: var(--spacing-sm);
}

.edit-tabs .Wt-tabs {
    display: flex;
    align-items: flex-end;
    gap: var(--spacing-xs);
    padding: 0 var(--spacing-sm);
    margin: 0;
    list-style: none;
    border-bottom: 1px solid var(--gray-300);
    background: var(--gray-100);
}

.edit-tabs .Wt-tabs li {
    list-style: none;
    margin: 0;
    padding: 0;
}

.edit-tabs .Wt-tabs li a,
.edit-tabs .Wt-tabs li button {
    display: block;
    padding: var(--spacing-sm) var(--spacing-md);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    border: 1px solid transparent;
    font-size: var(--font-size-base);
    font-weight: 500;
    text-decoration: none;
    background: transparent;
    color: var(--primary);
    cursor: pointer;
}

.edit-tabs .Wt-tabs li a:hover,
.edit-tabs .Wt-tabs li button:hover {
    background: var(--primary-light);
}

.edit-tabs .Wt-tabs li.Wt-selected a,
.edit-tabs .Wt-tabs li.Wt-selected button {
    background: var(--white);
    color: var(--primary);
    border-color: var(--gray-300);
    border-bottom-color: var(--white);
}

.edit-tabs .Wt-stack {
    border: 1px solid var(--gray-300);
    border-radius: 0 var(--radius-lg) var(--radius-lg) var(--radius-lg);
    padding: var(--spacing-lg) var(--spacing-xl);
    background: var(--white);
    margin-top: -1px;
}

/* Name-slot sub-tabs (Name 1..4) inside the part Names tab. Replaces Wt's
   default WTabWidget chrome with the flat app look. */
/* Name-slot sub-tabs (a CustomTabs): compact rounded pills so the 4 slots read
   as a secondary, lighter control under the main editor tabs. */
.name-slot-tabs .ctabs-bar {
    gap: 6px;
    padding: 8px 0 10px;
    border-bottom: none;
    background: transparent;
    position: static;
    flex-wrap: wrap;
}
.name-slot-tabs .ctabs-bar .ctabs-tab {
    padding: 5px 16px;
    border: 1px solid var(--gray-300);
    border-radius: 999px;
    background: var(--gray-100);
    color: var(--gray-700);
    font-weight: 500;
    box-shadow: none;
}
.name-slot-tabs .ctabs-bar .ctabs-tab:hover {
    background: var(--gray-200);
    color: var(--primary-dark);
    box-shadow: none;
}
.name-slot-tabs .ctabs-bar .ctabs-tab--active,
.name-slot-tabs .ctabs-bar .ctabs-tab--active:hover {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--white);
    box-shadow: none;
}
.name-slot-tabs .ctabs-stack {
    padding: 12px 0 0;
}

/* Names Scroll Area */
.names-scroll-area {
    max-height: 400px;
    overflow-y: auto;
    border: 1px solid #e5e7eb;
    border-radius: var(--radius-lg);
    background-color: var(--white);
    padding: var(--spacing-sm) var(--spacing-md);
}

.names-scroll-area .lang-row {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    margin-bottom: 6px;
    min-height: 32px;
}

.names-scroll-area .lang-label {
    min-width: 120px;
    font-size: var(--font-size-sm);
    color: var(--gray-700);
}

/* ============================================
   MACHINE PAGE LAYOUT
   ============================================ */
.machine-page-layout {
    display: flex;
    width: 100%;
    height: calc(100vh - 130px);
    overflow: hidden;
    background: #f5f5f5;
    display: flex;
}

.panel-layout {
    display: flex;
    width: 100%;
    height: 100%;
    min-height: calc(100vh - 130px);
    position: relative;
}

/* Left Panel */
.panel-left, .machine-page-layout .panel-left {
    width: var(--sidebar-width);
    min-width: var(--sidebar-min);
    max-width: 500px;
    height: 100%;
    background: var(--white);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    flex-shrink: 0;
    transition: width var(--transition-base);
}

.panel-left.collapsed {
    width: var(--sidebar-min) !important;
}

.panel-left.collapsed .assembly-tree-content,
/* Sidebar open: the tree header shows the assembly name, so the bar pill would
   only repeat it — drop it and hand the space back to the nowrap bar. Collapsed,
   the 56px rail cannot hold a name (rule below hides it) and the pill takes over.
   .panel-left and .panel-center are siblings, so this needs no JS to stay in sync. */
.panel-left:not(.collapsed) ~ .panel-center .assembly-bar-name {
    display: none;
}

.panel-left.collapsed .assembly-tree-header-title,
.panel-left.collapsed .assembly-tree-search {
    display: none;
}

/* Center Panel */
.panel-center, .machine-page-layout .panel-center {
    flex: 1;
    min-width: 300px;
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--white);
}

.panel-right {
    flex: 1;
    min-width: 0;
    overflow: auto;
    background: var(--white);
}

.center-content-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: #fafafa;
    min-height: 0;
}

.viewer-wrapper, .bom-wrapper {
    min-height: 100px;
    background: var(--white);
    border: 1px solid #e0e0e0;
    border-radius: 6px;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.viewer-wrapper {
    flex: 1 1 50vh;
    overflow: auto;
}

.bom-wrapper {
    flex: 1 1 34vh;
    min-height: 0;
    overflow-y: auto;
}

/* Dismissible notice at the top of the assembly content area, shown when a
   hotspot/link/machine-number switch redirected to a visible sibling
   version (see MachinePage::notifyVersionSubstituted). flex:0 so it never
   competes with the viewer/BOM wrappers for space. */
.version-notice-banner {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 12px;
    margin-bottom: 8px;
    border-radius: 6px;
    background: #fff3cd;
    border: 1px solid #ffe69c;
    color: #664d03;
    font-size: calc(13px * var(--font-scale));
}

.version-notice-banner-text {
    flex: 1;
}

.version-notice-banner-dismiss {
    flex: 0 0 auto;
    background: transparent;
    border: none;
    padding: 2px 4px;
    color: inherit;
}

/* When a children list is shown beneath the assembly SVG, let the SVG
   viewer take only the remaining flex space. Fixed vh heights caused
   the fit calculation to ignore the lower list and over-zoom the SVG. */
.assembly-viewer.assembly-viewer-capped {
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
    max-height: none;
    overflow: hidden;
}

.assembly-viewer.assembly-viewer-capped .svg-viewer {
    flex: 1 1 auto;
    height: 100%;
    min-height: 0;
}

.assembly-viewer.assembly-viewer-capped .svg-viewer-wrapper {
    flex: 1 1 auto;
    min-height: 0;
    height: auto;
}

/* ============================================
   RESIZERS
   ============================================ */
.panel-resizer {
    flex-shrink: 0;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background var(--transition-base);
    position: relative;
}

.vertical-resizer {
    width: 6px;
    height: 100%;
    cursor: col-resize;
}

.vertical-resizer::after {
    content: '';
    /* Flex item (not absolutely positioned) so both left and right
       resizers compute the pill's y from the same flex layout pass.
       Absolute positioning was drifting by ~1-2px between the two
       resizers under Wt's layout. */
    align-self: flex-start;
    margin-top: calc(var(--header-height, 60px) + 50px);
    width: 2px;
    height: 30px;
    background: #198754;
    border-radius: 1px;
    opacity: 0.8;
}

.panel-resizer:hover::after {
    opacity: 1;
}

.horizontal-resizer {
    width: 100%;
    height: 8px;
    cursor: row-resize;
    margin: 0;
    border-radius: var(--radius-sm);
    touch-action: none;
    position: relative;
}

/* Sub-assemblies toggle: the strip is repurposed as a toggle bar — we
   hide the visible grip lines so only the arrow button shows. */
.horizontal-resizer::before,
.horizontal-resizer::after {
    content: none !important;
}

.horizontal-resizer::after {
    content: '';
    width: 40px;
    height: 3px;
    background: rgba(255,255,255,0.8);
    border-radius: 2px;
    position: relative;
}

.horizontal-resizer:hover {
    background: rgba(25,135,84,0.08);
}

.panel-resizer-right {
    width: 6px;
    background: var(--primary);
    cursor: col-resize;
}

.panel-resizer-right::after {
    content: '';
    width: 2px;
    height: 30px;
    background: var(--white);
    border-radius: 1px;
    opacity: 0.85;
}

.panel-resizer-right:hover {
    background: #157347;
}

/* ============================================
   ASSEMBLY TREE
   ============================================ */
.assembly-tree {
    height: 100%;
    display: flex;
    flex-direction: column;
    background: var(--white);
}

.assembly-tree-header {
    background: var(--primary);
    color: var(--white);
    padding: 0 var(--spacing-md);
    /* !important because Wt's WVBoxLayout sets an explicit inline
       height on flex children, which would otherwise pin the header
       to its original 60px even after --header-height grows. */
    min-height: var(--header-height, 60px) !important;
    height: var(--header-height, 60px) !important;
    display: flex;
    align-items: center;
}

/* The header is a flex item of the column-direction .panel-left; without this
   its automatic min-width follows the title text, so a long assembly name
   pushes the header wider than the panel, the panel clips it, and the title
   never shrinks for AssemblyNameFitJs. */
#machine-left-panel .assembly-tree-header {
    min-width: 0 !important;
    max-width: 100% !important;
    overflow: hidden;
    box-sizing: border-box;
}
#machine-left-panel .assembly-tree-header .assembly-tree-header-clickable {
    min-width: 0 !important;
}

.assembly-tree-header-clickable {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: var(--header-height, 60px);
    /* No cursor here any more: the container itself is not clickable, only the
       burger icon and the title are, and each sets its own. */
}

/* The header used to be one big button; now the burger toggles the sidebar and
   the title scrolls the tree, so its children must receive their own clicks. */
.assembly-tree-header-icon,
.assembly-tree-header .assembly-tree-header-title {
    pointer-events: auto;
    cursor: pointer;
}

.assembly-tree-header-icon {
    font-size: var(--font-size-xl);
    margin-right: var(--spacing-sm);
}

/* Chip look comes from the shared .assembly-bar-pill block below. Here only the
   sidebar specifics: hug the text instead of spanning the header (Wt's layout
   sets an inline flex-grow, hence !important), and clip a long assembly name
   rather than pushing the header wide. */
.assembly-tree-header .assembly-tree-header-title {
    flex: 0 1 auto !important;
    min-width: 0;
    max-width: 100%;
    /* Two classes on purpose: the shared pill block sits lower in this file and
       would otherwise win on order and re-apply inline-flex, under which
       text-overflow never takes effect. */
    display: block;
    line-height: 30px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Live filter row between the tree header and the tree content. */
.assembly-tree-search {
    position: relative;
    padding: 6px 10px;
    border-bottom: 1px solid var(--gray-200);
    flex-shrink: 0;
}

.assembly-tree-search-input {
    width: 100%;
    box-sizing: border-box;
    padding: 6px 26px 6px 8px;
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-md);
    background: var(--white);
    color: var(--gray-800);
    font-size: var(--font-size-sm);
}

.assembly-tree-search-input:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 2px rgba(25,135,84,0.15);
}

.assembly-tree-search-input::placeholder {
    color: var(--gray-500);
}

/* Clear (x) icon, absolutely positioned over the input's right padding. */
.assembly-tree-search-clear {
    position: absolute;
    top: 50%;
    right: 16px;
    transform: translateY(-50%);
    width: 14px;
    height: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--gray-500);
    font-size: var(--font-size-xs);
    cursor: pointer;
    border-radius: 50%;
}

.assembly-tree-search-clear:hover {
    color: var(--gray-800);
    background: var(--gray-200);
}

.assembly-tree-content {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
}

.assembly-tree-item {
    border-bottom: 1px solid #f0f0f0;
}

.assembly-tree-item:last-child {
    border-bottom: none;
}

.assembly-tree-row {
    display: flex;
    align-items: center;
    padding: var(--spacing-xs) var(--spacing-xs);
    cursor: pointer;
    transition: background var(--transition-fast);
    gap: var(--spacing-sm);
}

.assembly-tree-row:hover {
    background: #f5f5f5;
}

.assembly-tree-row.selected {
    background: #c3e6cb;
    border-left: 3px solid var(--primary);
}

.assembly-tree-row.hovered {
    background-color: var(--primary-light);
}

/* Dimmed row: sheet not available for the currently selected machine.
   Non-interactive for selection, but the expand/collapse toggle stays
   clickable (no pointer-events change on the row). */
.assembly-tree-row.assembly-tree-row-hidden {
    opacity: .55;
    cursor: default;
}

.assembly-tree-row.assembly-tree-row-hidden:hover,
.assembly-tree-row.assembly-tree-row-hidden.hovered,
.assembly-tree-row.assembly-tree-row-hidden.selected {
    background: transparent;
    background-color: transparent;
    border-left: none;
}

/* Catalog editors: a fully-hidden row keeps its dimmed look and badge, but
   stays interactive (row->clicked()/doubleClicked() are connected for it),
   so the click/hover/selected states above are restored here. Four classes
   outweigh the three-class neutralizing rules above regardless of order. */
.assembly-tree-row.assembly-tree-row-hidden.assembly-tree-row-hidden-editable {
    cursor: pointer;
}

.assembly-tree-row.assembly-tree-row-hidden.assembly-tree-row-hidden-editable:hover {
    background: #f5f5f5;
}

.assembly-tree-row.assembly-tree-row-hidden.assembly-tree-row-hidden-editable.hovered {
    background-color: var(--primary-light);
}

.assembly-tree-row.assembly-tree-row-hidden.assembly-tree-row-hidden-editable.selected {
    background: #c3e6cb;
    border-left: 3px solid var(--primary);
}

.assembly-tree-toggle {
    width: 14px;
    height: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--gray-600);
    font-size: calc(10px * var(--font-scale));
    flex-shrink: 0;
    transition: transform var(--transition-base);
}

.assembly-tree-toggle:hover {
    color: var(--primary);
}

.assembly-tree-toggle.expanded {
    transform: rotate(90deg);
}

.assembly-tree-toggle.hidden {
    visibility: hidden;
}

.assembly-tree-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.assembly-tree-name {
    font-size: var(--font-size-sm);
    color: var(--gray-800);
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.assembly-tree-code {
    font-family: var(--font-mono);
    font-size: var(--font-size-xs);
    color: var(--gray-500);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.assembly-tree-meta {
    display: none !important;
}

.assembly-tree.show-codes .assembly-tree-meta {
    display: block !important;
}

.assembly-tree-children {
    display: none;
}

.assembly-tree-children.expanded {
    display: block;
}

/* Tree Levels */
.assembly-tree-level-0 > .assembly-tree-row { padding-left: 12px; }
.assembly-tree-level-1 > .assembly-tree-row { padding-left: 24px; }
.assembly-tree-level-2 > .assembly-tree-row { padding-left: 36px; }
.assembly-tree-level-3 > .assembly-tree-row { padding-left: 48px; }
.assembly-tree-level-4 > .assembly-tree-row { padding-left: 60px; }

.assembly-tree-level-0 > .assembly-tree-row.selected { padding-left: 9px; }
.assembly-tree-level-1 > .assembly-tree-row.selected { padding-left: 21px; }
.assembly-tree-level-2 > .assembly-tree-row.selected { padding-left: 33px; }
.assembly-tree-level-3 > .assembly-tree-row.selected { padding-left: 45px; }
.assembly-tree-level-4 > .assembly-tree-row.selected { padding-left: 57px; }

.assembly-tree-empty {
    padding: 30px var(--spacing-xl);
    text-align: center;
    color: #999;
    font-size: var(--font-size-sm);
}

/* Scrollbar */
.assembly-tree-content::-webkit-scrollbar {
    width: 5px;
}

.assembly-tree-content::-webkit-scrollbar-track {
    background: transparent;
}

.assembly-tree-content::-webkit-scrollbar-thumb {
    background: var(--gray-300);
    border-radius: 3px;
}

/* ============================================
   ASSEMBLY BAR
   ============================================ */
.assembly-bar {
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    color: var(--white);
    /* Fixed floor (not var(--header-height)) so the bar shrinks freely
       when content unwraps. The JS publishes the bar's measured height
       into --header-height; if the bar's own floor depended on the var,
       a feedback loop would lock the bar at its peak height.
       48px matches the green bar in AlbachTrac and usermanagementWT. */
    min-height: 48px;
    flex-shrink: 0;
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
    /* Query container for bar rules that depend on the bar's own width
       (the part info sidebar narrows it without a viewport change). */
    container: assembly-bar / inline-size;
}

.assembly-bar-top {
    display: flex;
    align-items: center;
    min-height: 48px;
    gap: var(--spacing-md);
    padding: 4px var(--spacing-lg);
    /* Single line at every width: the title pill is the only shrinkable
       item (min-width:0 + ellipsis); wrapping would make row count depend
       on content width and jump between breakpoints. */
    flex-wrap: nowrap;
}

/* Dropdown labels are hidden once the bar gets tight; the combos stay and
   already show the value, so the label carries no extra information. The bar
   is a single nowrap row whose only shrinkable items are the title pill and
   the note chip — everything else is flex-shrink:0, so the labels are the
   first thing to give up before the row overflows. */
@media only screen and (max-width: 1200px) {
    .assembly-bar-control-label {
        display: none;
    }
}
/* Same when only the bar is narrow (side panels open on a wide screen). */
@container assembly-bar (max-width: 900px) {
    .assembly-bar-control-label {
        display: none;
    }
}

.assembly-bar-left {
    display: flex;
    align-items: center;
    gap: var(--spacing-xl);
    flex: 1;
    min-width: 0;
}

.assembly-bar-code {
    font-family: var(--font-mono);
    font-size: var(--font-size-xl);
    font-weight: 600;
    letter-spacing: 1px;
    white-space: nowrap;
}

.assembly-bar-name {
    font-size: var(--font-size-lg);
    font-weight: 600;
    line-height: 1.2;
    min-width: 0;
    flex: 0 1 auto;
    /* Pill keeps white-space:nowrap; clip with ellipsis when the flex
       item shrinks below its content width on narrow screens. */
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Shared pill look for header-bar chips (assembly title, ET-code dropdown) and
   for the sidebar header title, so both sides of the green strip look alike.
   Fixed height keeps all bar items (pills and dropdowns) equally tall. */
.assembly-bar-pill,
.assembly-tree-header-title {
    display: inline-flex;
    align-items: center;
    height: 32px;
    box-sizing: border-box;
    padding: 0 12px;
    background: rgba(255,255,255,0.15);
    color: #fff;
    border: 1px solid rgba(255,255,255,0.4);
    border-radius: 4px;
    cursor: pointer;
    font-weight: 600;
    white-space: nowrap;
    transition: background 0.15s ease, transform 0.15s ease;
}
.assembly-bar-pill:hover {
    background: rgba(255,255,255,0.25);
    transform: translateY(-1px);
}
.assembly-bar-pill:active {
    transform: translateY(0);
}

/* Assembly-name text in the bar pill and the sidebar header title.
   AssemblyNameFitJs shrinks it on one line, then adds .assembly-bar-name-2l
   for two lines inside the same pill height. The bar pill centres it through
   its inline-flex; the header title (display:block, line-height:30px) centres
   one line by line-height and two lines through the rule below. */
.assembly-bar-name .assembly-bar-name-text,
.assembly-tree-header-title .assembly-bar-name-text {
    display: block;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.assembly-bar-name.assembly-bar-name-2l .assembly-bar-name-text,
.assembly-tree-header-title.assembly-bar-name-2l .assembly-bar-name-text {
    white-space: normal !important;
    display: -webkit-box !important;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    line-height: 1.15 !important;
    overflow-wrap: anywhere;
    text-overflow: clip;
}
/* Scoped to the open sidebar so the collapsed-panel display:none still wins. */
.panel-left:not(.collapsed) .assembly-tree-header .assembly-tree-header-title.assembly-bar-name-2l {
    display: flex;
    align-items: center;
}

/* Direct Export PDF pill (users without the ET-code dropdown). */
.assembly-bar-pdf img {
    width: 18px;
    height: 18px;
    margin: 0 6px 0 0;
    flex-shrink: 0;
    filter: brightness(0) invert(1);
}

/* ET-code pill: compact so the title keeps as much width as possible. */
.assembly-bar-et {
    padding: 0 8px;
    font-size: var(--font-size-sm);
    letter-spacing: 0;
}
.assembly-bar-et img {
    width: 15px;
    height: 15px;
    margin: 0 3px 0 0;
    flex-shrink: 0;
    /* White chevron; thin strokes vanish below ~14px on the green bar. */
    filter: brightness(0) invert(1) drop-shadow(0 0 0.5px rgba(255,255,255,0.9));
}
/* Read-only ET-code pill (no dropdown): no click affordance, text copyable. */
.assembly-bar-et-static {
    cursor: default;
    user-select: text;
}
.assembly-bar-et-static:hover {
    background: rgba(255,255,255,0.15);
    transform: none;
}

/* Compact icon-only 3D pill next to the ET code. */
.assembly-bar-3d-btn {
    padding: 0 8px;
    line-height: 0;
}
.assembly-bar-3d-btn img {
    width: 16px;
    height: 16px;
    filter: brightness(0) invert(1);
    display: block;
}

/* 3D icon in the BOM details column; spaced when next to the detail button. */
.bom-details-col .part-detail-icon-btn + .btn-icon-3d {
    margin-left: 2px;
}

/* Compact icons in the BOM details column: the column is sized to hold up to
   three of them, so their footprint sets its width. */
.bom-table .bom-details-col .part-detail-icon-btn {
    width: 24px;
    height: 24px;
}

.bom-table .bom-details-col .btn-icon {
    padding: 2px;
}

.assembly-bar-note-inline {
    display: flex;
    align-items: center;
    gap: 6px;
    background: rgba(255,255,255,0.15);
    padding: var(--spacing-xs) var(--spacing-sm);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    min-width: 0;
    flex: 0 1 auto;
    max-width: 100%;
}

.assembly-bar-note-inline .assembly-bar-note-text {
    opacity: 0.95;
    overflow: hidden;
    text-overflow: ellipsis;
    /* Ellipsis needs a single line, and min-width:0 lets the flex item shrink
       below the note's own width instead of stretching the bar. */
    white-space: nowrap;
    min-width: 0;
}

.assembly-bar-version, .assembly-bar-control {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    flex-shrink: 0;
    font-size: var(--font-size-sm);
    white-space: nowrap;
}

.assembly-bar-version select,
.assembly-bar-dropdown {
    background: rgba(255,255,255,0.2);
    border: 1px solid rgba(255,255,255,0.4);
    color: var(--white);
    height: 32px;
    box-sizing: border-box;
    padding: 0 30px 0 12px;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    cursor: pointer;
    min-width: 60px;
}

.assembly-bar-version select:hover,
/* Version selector: trigger button + popup list, not a native select. A
   select sizes itself to its widest option, so the "compare" entry would set
   the closed control's width; here the trigger only ever shows the current
   "V07" / "V07 (Draft)" and the option list sizes independently. */
.version-selector-trigger.Wt-btn {
    position: relative;
    width: auto;
    min-width: 62px;
    justify-content: flex-start;
    text-align: left;
    white-space: nowrap;
    margin: 0;
}

.version-selector-trigger::after {
    content: "\25BE";
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    font-size: calc(10px * var(--font-scale));
}

.version-selector-popup {
    z-index: 1300;
    min-width: 150px;
    max-width: calc(100vw - 20px);
    padding: 6px;
    box-sizing: border-box;
    background: var(--white);
    color: var(--gray-800);
    border: 0;
    border-radius: 10px;
    box-shadow: 0 4px 16px rgba(15,23,42,0.18);
}

.version-selector-heading {
    padding: 2px 12px 6px;
    color: var(--gray-500);
    font-size: var(--font-size-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.version-selector-list {
    max-height: 260px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.version-selector-option.Wt-btn,
.version-selector-compare.Wt-btn {
    display: block !important;
    width: 100%;
    min-height: 34px;
    margin: 0 !important;
    padding: 7px 12px !important;
    border: 0 !important;
    border-radius: 4px !important;
    background: transparent !important;
    color: var(--gray-800) !important;
    text-align: left;
    justify-content: flex-start;
    white-space: nowrap;
}

.version-selector-option:hover,
.version-selector-compare:hover {
    background: var(--gray-100) !important;
}

/* Current version. Darker green than --success (#28a745) for readable text on
   the tinted background. */
.version-selector-option.Wt-btn.selected {
    background: rgba(40, 167, 69, 0.14) !important;
    color: #1b7a35 !important;
    font-weight: 700;
    box-shadow: inset 3px 0 0 var(--success);
}

.version-selector-option.Wt-btn.selected:hover {
    background: rgba(40, 167, 69, 0.22) !important;
}

/* Second line of a version option (note and machine-number range). The
   max-width also caps how wide a long note can make the popup. */
.version-selector-option.Wt-btn .version-selector-option-note {
    max-width: 260px;
    margin: 1px auto 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--font-size-xs);
    font-weight: 400;
    color: var(--gray-600);
}

/* Action entry, separated from the version numbers above it. */
.version-selector-compare.Wt-btn {
    margin-top: 5px !important;
    padding-top: 10px !important;
    border-top: 1px solid var(--gray-200) !important;
    border-radius: 0 !important;
    font-weight: 600;
}

.assembly-bar-dropdown:hover {
    background-color: rgba(255,255,255,0.3);
}

.assembly-bar-version select option,
.assembly-bar-dropdown option {
    background: var(--primary);
    color: var(--white);
}

.assembly-machine-number-trigger.Wt-btn {
    position: relative;
    width: 92px;
    min-width: 92px;
    justify-content: flex-start;
    text-align: left;
    margin: 0;
}
.assembly-machine-number-trigger::after {
    content: "▾";
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    font-size: calc(13px * var(--font-scale));
}

.assembly-machine-number-popup {
    z-index: 1300;
    width: 340px;
    max-width: calc(100vw - 20px);
    padding: 12px 10px 10px;
    box-sizing: border-box;
    background: var(--white);
    color: var(--gray-800);
    border: 0;
    border-radius: 10px;
    box-shadow: 0 4px 16px rgba(15,23,42,0.18);
}
.assembly-machine-number-search-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.assembly-machine-number-filter {
    flex: 1 1 auto;
    min-width: 0;
    height: 36px;
    box-sizing: border-box;
    padding: 6px 11px;
    border: 1px solid var(--primary);
    border-radius: 6px;
    outline: none;
    color: var(--gray-800);
    background: var(--white);
}
.assembly-machine-number-filter:focus {
    border-color: var(--primary-dark);
    box-shadow: 0 0 0 2px rgba(0,105,62,0.10);
}
.assembly-machine-number-close.Wt-btn {
    flex: 0 0 36px;
    width: 36px;
    height: 36px;
    min-width: 36px;
    margin: 0 !important;
    padding: 0 !important;
    border: 1px solid var(--gray-300) !important;
    border-radius: 6px !important;
    background: var(--white) !important;
    color: var(--gray-600) !important;
    font-size: calc(25px * var(--font-scale));
    line-height: 32px;
    font-weight: 300;
}
.assembly-machine-number-close:hover {
    background: var(--gray-100) !important;
    color: var(--gray-800) !important;
}
.assembly-machine-number-heading {
    margin-top: 8px;
    padding: 9px 12px;
    border: 1px solid var(--gray-200);
    border-bottom: 0;
    border-radius: 6px 6px 0 0;
    background: var(--gray-100);
    color: var(--gray-600);
    font-size: calc(11px * var(--font-scale));
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.assembly-machine-number-list {
    max-height: 260px;
    overflow-y: auto;
    overscroll-behavior: contain;
    border: 1px solid var(--gray-200);
    border-radius: 0 0 6px 6px;
    background: var(--white);
}
.assembly-machine-number-option.Wt-btn {
    display: block !important;
    width: 100%;
    min-height: 38px;
    margin: 0 !important;
    padding: 8px 12px !important;
    border: 0 !important;
    border-radius: 0 !important;
    border-bottom: 1px solid var(--gray-100) !important;
    background: transparent !important;
    color: var(--gray-800) !important;
    text-align: left;
    justify-content: flex-start;
}
.assembly-machine-number-option:hover,
.assembly-machine-number-option.selected {
    background: var(--gray-100) !important;
}
/* Search filter hit. Needs to outrank the `display: block !important` above,
   which is why it repeats both classes. */
.assembly-machine-number-option.Wt-btn.filtered-out {
    display: none !important;
}

.assembly-bar-note { display: none; }

/* Part detail bar: back | title | actions. The title is the only item that
   shrinks; its zero flex-basis keeps the unwrapped part name from claiming
   row width, so the back button and the actions always keep their size. */
.part-detail-bar .part-detail-back {
    flex: 0 0 32px;
    width: 32px;
    height: 32px;
    min-width: 32px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(255,255,255,0.15);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.part-detail-bar .part-detail-back:hover {
    background: rgba(255,255,255,0.25);
}
.part-detail-bar .part-detail-back img {
    width: 18px;
    height: 18px;
    /* White chevron; same treatment as the ET pill icon. */
    filter: brightness(0) invert(1) drop-shadow(0 0 0.5px rgba(255,255,255,0.9));
}

/* Single text line: the ellipsis eats the name first, then the number. */
.part-detail-bar .part-detail-title {
    display: block;
    flex: 1 1 0%;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #fff;
    font-size: var(--font-size-lg);
    line-height: 1.2;
}
.part-detail-bar .part-detail-nr {
    font-weight: 600;
}
.part-detail-bar .part-detail-sep {
    color: rgba(255,255,255,0.7);
    white-space: pre;
}
.part-detail-bar .part-detail-name {
    color: rgba(255,255,255,0.85);
    font-weight: 400;
}

.part-detail-bar .part-detail-actions {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    flex: 0 0 auto;
}

.part-detail-bar .part-detail-action {
    flex: 0 0 auto;
    height: 32px;
    padding: 0 10px;
    border: none;
    border-radius: var(--radius-sm);
    background: rgba(255,255,255,0.15);
    color: #fff;
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
    cursor: pointer;
    font-size: var(--font-size-sm);
}
.part-detail-bar .part-detail-action:hover {
    background: rgba(255,255,255,0.25);
}

/* Menu button for narrow screens: hidden here, shown by the MOBILE DIALOG
   CONTRACT block once it hides .part-detail-actions there. Plain text node
   (no icon, no span), so the app-wide `button span` rule does not apply.
   !important is required: `.Wt-btn { display:inline-flex !important }`. */
.part-detail-bar .part-detail-more {
    display: none !important;
    flex: 0 0 32px;
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    border-radius: var(--radius-sm);
    background: rgba(255,255,255,0.15);
    color: #fff;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
}
.part-detail-bar .part-detail-more:hover {
    background: rgba(255,255,255,0.25);
}

/* Menu mode when the bar itself is narrow (e.g. part info sidebar open). */
@container assembly-bar (max-width: 640px) {
    .part-detail-bar .part-detail-actions {
        display: none !important;
    }
    .part-detail-bar .part-detail-more {
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
    }
}

@media only screen and (max-width: 480px) {
    .part-detail-bar .part-detail-sep,
    .part-detail-bar .part-detail-name {
        display: none;
    }
}

/* ============================================
   ASSEMBLY CONTENT
   ============================================ */
.assembly-content {
    padding: 0;
    overflow: auto;
}

.assembly-image-panel, .assembly-image-container {
    background: var(--gray-100);
    border-radius: var(--radius-lg);
    padding: var(--spacing-lg);
    text-align: center;
}

.assembly-image {
    max-width: 100%;
    height: auto;
    border-radius: 6px;
}

.assembly-no-image {
    padding: 50px;
    color: var(--gray-500);
    font-style: italic;
}

.assembly-viewer-panel {
    min-height: 300px;
    max-height: 500px;
    border: 1px solid #e0e0e0;
    border-radius: 6px;
    overflow: hidden;
}

/* ============================================
   BOM VIEWER
   ============================================ */
.bom-viewer-container {
    background: var(--white);
    border-radius: var(--radius-lg);
    overflow: auto;
    padding: var(--spacing-lg);
    border: 1px solid var(--gray-200);
    box-shadow: 0 1px 5px rgba(0,0,0,0.05);
    min-height: 150px;
    height: 100%;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
}

.bom-empty-message {
    padding: var(--spacing-xl);
    text-align: center;
    color: #999;
    font-style: italic;
}

.bom-assembly-link {
    color: var(--primary);
    cursor: pointer;
    text-decoration: underline;
    font-weight: 500;
}

.bom-assembly-link:hover {
    color: var(--primary-dark);
}

.bom-table-wrapper {
    border: 1px solid #e5e7eb;
    border-radius: var(--radius-lg);
    background-color: var(--white);
    overflow: auto;
    flex: 1 1 auto;
    min-height: 0;
}

/* BOM quick filter: the header toggle opens a slim field that overlays the
   header row from a zero-height anchor above the table; on phones the field
   becomes its own slim row while open. Rows are hidden in the browser. */
.bom-filter-anchor {
    flex: 0 0 auto;
    position: relative;
    height: 0;
    z-index: 6;
}

.bom-filter-pop {
    position: absolute;
    top: 3px;
    right: 6px;
    width: 260px;
    max-width: calc(100% - 12px);
    height: 30px;
    display: none !important;
    align-items: center;
    gap: 6px;
    padding: 0 4px 0 10px;
    background: var(--white);
    border: 1.5px solid var(--primary);
    border-radius: 6px;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
    box-sizing: border-box;
}

.bom-filter-pop.bom-filter-open {
    display: flex !important;
}

.bom-filter-pop .bom-filter-input {
    flex: 1 1 auto;
    min-width: 0;
    width: auto !important;
    height: 26px !important;
    padding: 0 !important;
    margin: 0 !important;
    border: none !important;
    background: transparent !important;
    box-shadow: none !important;
    outline: none;
    font-size: calc(13px * var(--font-scale)) !important;
}

.bom-filter-count {
    flex: 0 0 auto;
    color: var(--gray-600);
    font-size: calc(11px * var(--font-scale));
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.bom-filter-clear {
    flex: 0 0 auto;
    padding: 2px 6px;
    border-radius: 4px;
    color: var(--gray-600);
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

.bom-filter-clear:hover {
    background: var(--gray-100);
    color: var(--gray-800);
}

.bom-filter-hidden {
    display: none !important;
}

.bom-tools-header-wrap .bom-filter-toggle {
    background-image: url('../files/essentials/search.svg') !important;
    background-repeat: no-repeat !important;
    background-position: center !important;
    background-size: 15px 15px !important;
}

.bom-tools-header-wrap .bom-filter-toggle.bom-filter-active {
    background-color: var(--primary-light) !important;
    box-shadow: inset 0 0 0 1.5px var(--primary);
}

@media (max-width: 768px), (hover: none) and (pointer: coarse) {
    .bom-filter-anchor {
        height: auto;
    }

    .bom-filter-pop {
        position: static;
        width: auto;
        max-width: none;
        height: 38px;
        margin-bottom: var(--spacing-sm);
        box-shadow: none;
    }

    .bom-filter-pop .bom-filter-input {
        height: 34px !important;
    }

    .bom-filter-clear {
        padding: 8px 10px;
    }
}

/* Spare width is shared out over every column instead of piling up in one:
   that only happens while each column states a px width and no max-width, so
   none of them is the single `auto` column that would swallow the remainder.
   The max-width is just a stop for ultra-wide monitors. */
.bom-table {
    font-size: var(--font-size-base);
    table-layout: auto;
    max-width: calc(1900px * var(--font-scale));
}

.bom-table th {
    background-color: #f1f3f4;
    color: var(--gray-700);
    font-weight: 700;
    font-size: 0.74em;
    text-align: left;
    padding: 4px var(--spacing-sm);
    border-bottom: 2px solid var(--gray-300);
    position: sticky;
    top: 0;
    z-index: 5;
}

.bom-table td {
    padding: 4px var(--spacing-sm);
    border-bottom: 1px solid #f1f1f1;
    vertical-align: middle;
    color: var(--gray-800);
    font-size: 0.82em;
}

.bom-table tr:nth-child(even) {
    background-color: #fafafa;
}

.bom-table tr:hover {
    background-color: var(--primary-light);
    cursor: pointer;
}

.bom-cell-center { text-align: center !important; vertical-align: middle !important; }
.bom-cell-right { text-align: right !important; }

/* Column widths below state a preferred share only — no min-width and no
   max-width anywhere. The stated width decides how spare width is split when
   the table has room; when it does not, auto layout shrinks every column
   towards its own min-content, so each floor is whatever that column's
   content actually needs. A px min-width would floor a column above its
   content and force a horizontal scrollbar that is not needed. */
.bom-table .bom-tools-col {
    width: calc(60px * var(--font-scale));
    padding-left: 4px;
    padding-right: 4px;
}

.bom-table .bom-cart-col {
    width: calc(56px * var(--font-scale));
    padding-left: 4px;
    padding-right: 4px;
}

.bom-table .bom-details-col {
    width: 42px;
    padding-left: 4px;
    padding-right: 4px;
}

@media (orientation: landscape) and (min-width: 720px) {
    /* nowrap keeps the three optional icons (detail, 3D, attachment) on one
       line; the column widens itself for such a row and stays narrow for the
       rows without icons. */
    .bom-table .bom-details-col {
        width: calc(56px * var(--font-scale));
        white-space: nowrap;
    }

    /* Do NOT use display:flex on a <td>: a flex cell is pulled out of the
       table row box, so an empty details cell collapses and the table
       background shows through as a white gap on colored/selected rows.
       Buttons are inline-flex; bom-cell-center handles centering. */
    .bom-table td.bom-details-col .btn-icon + .btn-icon {
        margin-left: 2px;
    }
}

@media (orientation: portrait) {
    .bom-table .bom-details-col {
        width: 42px;
        white-space: normal;
    }
}

.bom-table .bom-nr-col {
    width: calc(42px * var(--font-scale));
    padding-left: 6px;
    padding-right: 6px;
}

.bom-table .bom-image-col {
    width: 70px;
}

/* A stated px width, never `auto` and never a percentage: `auto` here makes
   this the column that absorbs all spare width, a percentage forces the table
   to stretch and dumps the remainder into the name column. nowrap makes the
   whole number the column's min-content, so it is never ellipsized. */
.bom-table .bom-code-col {
    width: calc(90px * var(--font-scale));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Widest share of the table, so it also takes the widest share of any spare
   width — proportionally, not all of it. */
.bom-table .bom-name-col {
    width: calc(300px * var(--font-scale));
    font-weight: 500;
    color: var(--gray-800);
    white-space: normal;
    overflow-wrap: break-word;
    word-break: normal;
}

.bom-table th.bom-name-col {
    font-size: calc(13px * var(--font-scale));
    font-weight: 700;
}

/* Replacement marker after the part name: icon, arrow, successor numbers. */
.bom-table .bom-replacement {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 3px;
    margin-left: 6px;
    font-size: .9em;
}

.bom-table .bom-replacement-link {
    color: #0d6efd;
    text-decoration: underline;
    cursor: pointer;
    font-weight: 600;
}

/* nowrap keeps "210/L" on one line instead of breaking after the slash. */
.bom-table .bom-qty-col {
    width: calc(46px * var(--font-scale));
    white-space: nowrap;
}

/* Right-aligned like price: the two number columns then sit next to each
   other instead of being separated by the gap left-alignment opens up. */
.bom-table .bom-weight-col {
    width: calc(68px * var(--font-scale));
    text-align: right;
}

/* nowrap keeps "1234.56 EUR" on one line and makes that string the column's
   floor. */
.bom-table .bom-price-col {
    width: calc(94px * var(--font-scale));
    white-space: nowrap;
}

/* Persistent GREEN row: cart-checkbox selected. Matches the green SVG layer;
   same tone as the hover highlight but sticky. */
.bom-row-cart td {
    background-color: rgba(76, 175, 80, 0.2) !important;
}

/* Active BLUE row: the part open in the info sidebar. Matches the blue SVG
   layer. Declared after .bom-row-cart so blue wins when a row is both. */
.bom-row-selected td {
    background-color: rgba(71, 73, 179, 0.15) !important;
    color: #34367f !important;
    font-weight: bold;
}

.bom-row-selected td:first-child {
    border-left: 5px solid #4749b3 !important;
}

.bom-row-highlight {
    background-color: rgba(76, 175, 80, 0.2) !important;
}

.bom-row-deleted td {
    opacity: 0.55;
    font-style: italic;
}

.bom-add-row-container {
    background-color: #f9fafb;
    border: 1px solid #e5e7eb;
    border-top: 1px solid var(--gray-200);
    border-radius: 0 0 6px 6px;
    padding: var(--spacing-xl);
}

.icon-has-details {
    font-size: var(--font-size-xl);
    text-align: center;
    display: flex;
    justify-content: center;
    align-items: center;
}

/* BOM Collapsible */
.bom-collapsible-container {
    display: flex;
    flex-direction: column;
    background: var(--white);
    border: 1px solid #e0e0e0;
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.bom-collapsible-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: var(--gray-100);
    padding: var(--spacing-sm) var(--spacing-md);
    border-bottom: 1px solid #e0e0e0;
    cursor: pointer;
}

.bom-collapsible-header:hover {
    background: #f0f0f0;
}

.bom-collapsible-title {
    font-weight: 600;
    font-size: var(--font-size-base);
    color: var(--gray-800);
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
}

.bom-collapsible-toggle {
    font-size: var(--font-size-sm);
    color: var(--gray-600);
    transition: transform var(--transition-base);
}

.bom-collapsible-toggle.collapsed {
    transform: rotate(-90deg);
}

.bom-collapsible-body {
    flex: 1;
    overflow: auto;
}

.bom-collapsible-body.collapsed {
    max-height: 0 !important;
    overflow: hidden;
}

/* ============================================
   SVG VIEWER
   ============================================ */
.svg-viewer {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--white);
    position: relative;
}

/* Armed state of the area-zoom tool. */
.svg-toolbar-btn-active {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--white);
}

/* Rubber band drawn while an area-zoom rectangle is being dragged. Never a
   pointer target, so the drag keeps reaching the wrapper underneath. */
.svg-zoom-marquee {
    position: absolute;
    z-index: 6;
    border: 1px dashed var(--primary);
    background: rgba(25, 135, 84, 0.12);
    pointer-events: none;
}

.svg-area-zoom-armed {
    cursor: crosshair;
}

/* SVG Viewer - Fixed centering.
   overflow starts hidden and both viewers switch it to auto once the drawing
   is fitted, so a zoomed drawing stays reachable. */
.svg-viewer-wrapper {
    position: relative;
    overflow: hidden;
    /* The drawing is dragged to pan; a text selection would autoscroll it. */
    user-select: none;
    background: #ffffff;
    display: flex;
    align-items: flex-start;
    justify-content: flex-start;
    flex: 1 1 auto;
    min-height: 0;
}

.svg-viewer-content {
    display: block;
    position: relative;
    flex-shrink: 0;
}

.svg-viewer-wrapper.svg-panning {
    cursor: grabbing !important;
}

.svg-viewer-wrapper:not(.svg-panning) {
    cursor: grab;
}
.svg-viewer-svg {
    display: block;
}

.svg-viewer-svg svg {
    display: block;
    max-width: none;
    height: auto;
}

/* No opacity transition. An animating opacity promotes the element to its own
   composited layer, which the browser rasterizes at the untransformed size and
   then stretches through the ancestor's scale() -- the drawing turns blurry for
   as long as a hotspot is highlighted. */
.svg-viewer-content [data-hotspot] {
    cursor: pointer;
}

/* No color/brightness change on direct hotspot hover; the hover feedback is
   the linked BOM row turning green. Avoids every hotspot flashing on mouseover. */

.svg-viewer-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    font-size: var(--font-size-base);
    color: var(--gray-500);
    font-style: italic;
}

/* Radial zoom dial overlaid on the drawing (see core/svg_zoom_dial_js).
   Collapsed it is a small translucent handle; hovering -- tapping on touch --
   expands it into reset at the centre, zoom in/out above and below, area zoom
   left and the pin toggle right. Pinning keeps it open across reloads. */
.svg-viewer-controls.svg-zoom-dial {
    position: absolute;
    top: var(--spacing-sm);
    right: var(--spacing-sm);
    width: 96px;
    height: 96px;
    /* Below Wt dialog (which defaults to ~1000+) so the dial doesn't
       punch through modal popups. */
    z-index: 100;
    /* No group opacity here. A translucent box stacked over the drawing forces
       the browser to composite it, and the SVG underneath then gets rastered at
       the pre-transform size -- the drawing looks blurry until the next zoom or
       pan re-rasters it. Transparency lives in the button colours instead. */
    /* The box is mostly empty while collapsed: clicks must reach the hotspots
       underneath, so only the buttons take pointer events. */
    pointer-events: none;
}

.svg-viewer-controls.svg-zoom-dial.is-open {
    /* Expanded, the whole box grabs the pointer so moving from the centre to a
       satellite never leaves the dial and collapses it mid-gesture. */
    pointer-events: auto;
}

/* Belt-and-suspenders: the absolute-positioned zoom controls can still bleed
   over a modal popup through stacking-context quirks. While any Wt dialog is
   open, hide the background machine viewer's controls outright. Scoped to
   .machine-page-layout so a dialog's own SVG controls stay visible. */
body:has(.Wt-dialog) .machine-page-layout .svg-viewer-controls {
    display: none !important;
}



/* Every dial button is centred on the dial and offset from there, so the ring
   geometry lives in one place (the transforms below). */
.svg-zoom-dial .szd-btn {
    position: absolute;
    left: 50%;
    top: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    border-radius: 50%;
    /* Alpha rides on the colours, not on a group opacity, so the dial never
       composites a translucent layer over the drawing. */
    background: rgba(24, 28, 33, 0.40);
    color: rgba(255, 255, 255, 0.78);
    cursor: pointer;
    pointer-events: auto;
    transition: background-color 0.16s ease, color 0.16s ease;
}

.svg-zoom-dial.is-open .szd-btn {
    background: rgba(24, 28, 33, 0.82);
    color: #ffffff;
}

.svg-zoom-dial .szd-btn:hover {
    background: var(--primary);
    color: #ffffff;
}

.svg-zoom-dial .szd-center {
    width: 30px;
    height: 30px;
    margin: -15px 0 0 -15px;
    z-index: 2;
}

.svg-zoom-dial .szd-sat {
    width: 28px;
    height: 28px;
    margin: -14px 0 0 -14px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.16s ease, transform 0.18s ease;
    /* Delays the collapse only: crossing the gap between the centre and a
       satellite must not close the dial. Reset to 0 while open. */
    transition-delay: 0.12s;
}

.svg-zoom-dial.is-open .szd-sat {
    opacity: 1;
    pointer-events: auto;
    transition-delay: 0s;
}

.svg-zoom-dial.is-open .szd-up    { transform: translate(0, -33px); }
.svg-zoom-dial.is-open .szd-down  { transform: translate(0, 33px); }
.svg-zoom-dial.is-open .szd-left  { transform: translate(-33px, 0); }
.svg-zoom-dial.is-open .szd-right { transform: translate(33px, 0); }

/* Single glyph slot. The centre icon is swapped in JS (neutral dots while
   collapsed, reset arrow once open), never by toggling two stacked nodes. */
.svg-zoom-dial .szd-ico {
    display: block;
    line-height: 0;
}

/* Pin held down, and the armed area-zoom tool, share the accent treatment. */
.svg-zoom-dial.is-pinned .szd-btn[data-zoom-pin],
.svg-zoom-dial .szd-btn.svg-toolbar-btn-active {
    background: var(--primary);
}

/* Sub-assembly overlay toggle: a fifth satellite on the lower-left diagonal,
   shown only when the viewer actually has an overlay to toggle. */
.svg-zoom-dial .szd-subasm {
    display: none;
}

#viewer-wrapper:has(> .subasm-overlay) .svg-zoom-dial .szd-subasm {
    display: flex;
}

.svg-zoom-dial.is-open .szd-downleft { transform: translate(-33px, 33px); }

/* Sub-assembly legend drawn over the bottom-left of the SVG (BOM + children +
   SVG). No box of its own: text sits on the drawing with a white halo, like
   the drawing's own labels. Visibility follows the overlay/list/hidden mode
   cycled by the dial button and by subAssembliesToggleBtn_; last mode
   persisted via sp_svgdial_subasm_mode. */
.subasm-overlay {
    position: absolute;
    left: var(--spacing-md);
    bottom: var(--spacing-md);
    z-index: 90;
    display: flex;
    flex-direction: column;
    /* Grows with the names up to 20% of the drawing pane width. */
    width: max-content;
    max-width: 20%;
    /* 25% of the drawing pane, never less than three rows. */
    --subasm-row-h: 22px;
    max-height: max(25%, calc(3 * var(--subasm-row-h)));
    background: transparent;
    pointer-events: none;
}

.subasm-overlay.is-hidden {
    display: none;
}

/* Portrait stacked layout (see machine-page-layout portrait grid): up to half the pane width. */
@media (orientation: portrait) and (min-width: 769px) {
    .subasm-overlay {
        max-width: 50%;
    }
}

.subasm-overlay-list {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: rgba(0, 0, 0, 0.25) transparent;
    scrollbar-gutter: stable;
    pointer-events: auto;
    /* rtl puts the scrollbar on the left; rows switch back to ltr. */
    direction: rtl;
}

.subasm-overlay-list > * {
    direction: ltr;
}

.subasm-overlay-row {
    display: flex;
    align-items: center;
    gap: 8px;
    box-sizing: border-box;
    height: var(--subasm-row-h);
    padding: 0 4px;
    border-radius: 12px;
    cursor: pointer;
}

.subasm-overlay-badge {
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--primary);
    color: var(--white);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
    box-shadow: 0 0 0 2px #fff;
}

.subasm-overlay-badge.is-empty {
    flex-basis: 6px;
    width: 6px;
    height: 6px;
    margin: 0 6px;
}

.subasm-overlay-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--font-size-sm);
    color: var(--gray-800, #343a40);
    text-shadow: 0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff;
}

.subasm-overlay-row:hover .subasm-overlay-name {
    color: var(--primary);
    text-decoration: underline;
}

/* Version chip after a sub-assembly name (overlay row and child card).
   Pill shape and weight follow .assembly-tree-version-badge. */
.subasm-version-tag {
    display: inline-block;
    flex: 0 0 auto;
    margin-left: 6px;
    padding: 0 7px;
    border-radius: 999px;
    background: var(--primary-light);
    color: var(--primary-dark);
    font-size: 0.74em;
    font-weight: 600;
    line-height: 16px;
    white-space: nowrap;
    vertical-align: middle;
}

/* Over the drawing: near-opaque fill so lines do not show through; no halo. */
.subasm-overlay-row > .subasm-version-tag {
    margin-left: 0;
    background: rgba(232, 245, 233, 0.94);
    box-shadow: 0 0 0 1px rgba(25, 135, 84, 0.25);
    text-shadow: none;
}

/* Anchors the overlay to the drawing pane, not the whole center panel. */
#viewer-wrapper:has(> .subasm-overlay) {
    position: relative;
}

/* Same belt-and-suspenders as .svg-viewer-controls: never bleed over a modal
   popup opened above the machine page. */
body:has(.Wt-dialog) .machine-page-layout .subasm-overlay {
    display: none !important;
}

/* Assembly-attached files: one row over the top-left of the SVG, or at the
   top of the viewer pane when there is no drawing. Never inside .assembly-bar. */
.assembly-files-strip {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 6px;
    min-width: 0;
    padding: 4px 8px;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
}

.assembly-files-strip.is-overlay {
    position: absolute;
    top: var(--spacing-md);
    left: var(--spacing-md);
    z-index: 90;
    max-width: 60%;
    background: rgba(255, 255, 255, 0.92);
    border: 1px solid #dee2e6;
    border-radius: var(--radius-sm);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
}

#viewer-wrapper:has(> .assembly-files-strip.is-overlay) {
    position: relative;
}

.assembly-files-strip .app-icon {
    flex: 0 0 auto;
}

.assembly-files-strip .assembly-files-btn {
    flex: 0 0 auto;
    max-width: 220px;
    padding: 3px 10px;
    background: #fff;
    border: 1px solid #ced4da;
    border-radius: var(--radius-sm);
    color: #333;
    font-size: 0.85em;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
}

.assembly-files-strip .assembly-files-btn:hover {
    background: #f0f4f8;
}

/* Single "Files (N)" toggle; the file list opens as .assembly-files-menu. */
.assembly-files-strip .assembly-files-toggle {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.assembly-files-strip .assembly-files-toggle img {
    width: 16px;
    height: 16px;
    margin: 0;
    flex-shrink: 0;
}

.assembly-files-strip .assembly-files-toggle::after {
    content: "";
    flex-shrink: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid currentColor;
    margin-left: 2px;
}

/* Long file names wrap inside the menu. The item text is a WLabel <span>
   whose inner WText <span> carries an inline `white-space: nowrap`; the icon
   is span.Wt-icon. */
.Wt-popupmenu.assembly-files-menu {
    max-width: min(420px, calc(100vw - 16px)) !important;
    box-sizing: border-box !important;
}

.Wt-popupmenu.assembly-files-menu li,
.Wt-popupmenu.assembly-files-menu a {
    max-width: 100% !important;
    box-sizing: border-box !important;
}

.Wt-popupmenu.assembly-files-menu a {
    align-items: flex-start !important;
}

.Wt-popupmenu.assembly-files-menu a > .Wt-icon {
    margin-top: 1px !important;
}

.Wt-popupmenu.assembly-files-menu a > span:not(.Wt-icon) {
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
    line-height: 1.35;
}

.Wt-popupmenu.assembly-files-menu a > span:not(.Wt-icon),
.Wt-popupmenu.assembly-files-menu a > span:not(.Wt-icon) span {
    white-space: normal !important;
}

@media (max-width: 768px) {
    .assembly-files-strip.is-overlay {
        max-width: calc(100% - 2 * var(--spacing-md));
    }
    .assembly-files-strip .assembly-files-btn {
        max-width: 140px;
    }
}

body:has(.Wt-dialog) .machine-page-layout .assembly-files-strip.is-overlay {
    display: none !important;
}

/* Hotspot Styles */
.svg-hotspot {
    cursor: pointer;
    pointer-events: all;
}

.svg-hotspot path, .svg-hotspot rect, .svg-hotspot polygon,
.svg-hotspot circle, .svg-hotspot ellipse {
    pointer-events: all;
}

/* Untagged hotspot.N groups (Pass 1 found no extractable code in their
   tooltip) sit on TOP of the label callouts in paint order, so they
   intercept mouseover events that should reach the labels below. Make
   them click-through so events pass through to the label box <g>
   that JS Pass 2 has tagged with data-hotspot. */
[id^="hotspot."]:not([data-hotspot]),
[id^="hotspot."]:not([data-hotspot]) * {
    pointer-events: none !important;
}

.svg-hotspot-highlight path, .svg-hotspot-highlight rect,
.svg-hotspot-highlight polygon, .svg-hotspot-highlight circle,
.svg-hotspot-highlight ellipse {
    fill: rgba(15, 142, 15, 0.48) !important;
    stroke: rgba(25, 135, 84, 0.6) !important;
    stroke-width: 2px !important;
}

/* Transparency lives in the paint, not in a group opacity: a group opacity
   renders the subtree into an offscreen buffer that the browser rasterizes at
   the untransformed size, so the drawing blurs while a hotspot is lit. It also
   faded the label text. Same approach as .svg-hotspot-active. */
.svg-hotspot-highlight {
    opacity: 1 !important;
}
/* Hotspot text stays dark so labels/numbers remain legible on the recolored
   callout box (a colored fill here would blend into the amber/green box).
   Descendant selectors cover the class landing on the wrapping <g>. */
text.svg-hotspot-highlight,
tspan.svg-hotspot-highlight,
.svg-hotspot-highlight text,
.svg-hotspot-highlight tspan {
  fill: #1f1f1f !important;
  stroke: none !important;
}

/* Part-detail drawings hotspot each label LINE, not the box: one box often
   lists several parts. The marker therefore lands on the <text>, and at this
   drawing's ~4pt type a fill change alone is not readable -- weight and a
   matching halo carry it. Colours follow the shared scheme: green on hover,
   violet for the part opened by click. */
/* Weight alone is too thin at this size, so the glyphs are also stroked in
   their own colour. paint-order puts the stroke behind the fill, which thickens
   the letters without smearing their shape. stroke-width is in user units
   against a ~4.14 font size. */
.svg-viewer-detail text.svg-hotspot-highlight,
.svg-viewer-detail tspan.svg-hotspot-highlight {
    fill: #0b7a0b !important;
    stroke: #0b7a0b !important;
    stroke-width: 0.42 !important;
    paint-order: stroke fill !important;
    font-weight: bold !important;
}

.svg-viewer-detail text.svg-hotspot-active,
.svg-viewer-detail tspan.svg-hotspot-active {
    fill: #3a3ca0 !important;
    stroke: #3a3ca0 !important;
    stroke-width: 0.42 !important;
    paint-order: stroke fill !important;
    font-weight: bold !important;
}

.svg-viewer-detail text.svg-hotspot-selected,
.svg-viewer-detail tspan.svg-hotspot-selected {
    fill: #0b7a0b !important;
    stroke: #0b7a0b !important;
    stroke-width: 0.42 !important;
    paint-order: stroke fill !important;
    font-weight: bold !important;
}

/* Persistent cart-checkbox selection highlight: same appearance as the
   transient hover highlight; separate class so hover does not clear it. */
.svg-hotspot-selected path, .svg-hotspot-selected rect,
.svg-hotspot-selected polygon, .svg-hotspot-selected circle,
.svg-hotspot-selected ellipse {
    fill: rgba(15, 142, 15, 0.48) !important;
    stroke: rgba(25, 135, 84, 0.6) !important;
    stroke-width: 2px !important;
}

/* Transparency lives in the paint, not in a group opacity: a group opacity
   renders the subtree into an offscreen buffer that the browser rasterizes at
   the untransformed size, so the drawing blurs while a hotspot is lit. It also
   faded the label text. Same approach as .svg-hotspot-active. */
.svg-hotspot-selected {
    opacity: 1 !important;
}
/* Hotspot text selection: dark for legibility on the green box. */
text.svg-hotspot-selected,
tspan.svg-hotspot-selected,
.svg-hotspot-selected text,
.svg-hotspot-selected tspan {
  fill: #1f1f1f !important;
  stroke: none !important;
}

/* Persistent BLUE layer: part opened by click (SVG/BOM -> info sidebar).
   Declared after the green selection layer so it wins when a hotspot is both
   click-active and cart-selected. */
/* Transparency lives in the fill, not in a group opacity: opacity here would
   fade the label text with the box and cost legibility. */
.svg-hotspot-active path, .svg-hotspot-active rect,
.svg-hotspot-active polygon, .svg-hotspot-active circle,
.svg-hotspot-active ellipse {
    fill: rgba(71, 73, 179, 0.45) !important;
    stroke: #34367f !important;
    stroke-width: 0.75px !important;
}

.svg-hotspot-active {
    opacity: 1 !important;
}
/* Hotspot text active: dark glyph, legible on the light blue box and on the
   white drawing alike. */
text.svg-hotspot-active,
tspan.svg-hotspot-active,
.svg-hotspot-active text,
.svg-hotspot-active tspan {
  fill: #1f1f1f !important;
  stroke: none !important;
}
/* Version-compare diff layers. Declared after the green/blue layers so they win
   inside the compare dialog. The three are told apart by stroke pattern as well
   as colour, so the added/removed distinction survives red-green colour
   blindness. Transparency lives in the fill, never in a group opacity — an
   opacity on the group rasterizes the subtree at the untransformed size and
   blurs the drawing (same reason as the layers above). */
.svg-hotspot-diff-added path, .svg-hotspot-diff-added rect,
.svg-hotspot-diff-added polygon, .svg-hotspot-diff-added circle,
.svg-hotspot-diff-added ellipse {
    fill: rgba(25, 135, 84, 0.42) !important;
    stroke: #146c43 !important;
    stroke-width: 2px !important;
    stroke-dasharray: none !important;
}

.svg-hotspot-diff-removed path, .svg-hotspot-diff-removed rect,
.svg-hotspot-diff-removed polygon, .svg-hotspot-diff-removed circle,
.svg-hotspot-diff-removed ellipse {
    fill: rgba(192, 57, 43, 0.40) !important;
    stroke: #a02b1e !important;
    stroke-width: 2px !important;
    stroke-dasharray: 6 3 !important;
}

.svg-hotspot-diff-changed path, .svg-hotspot-diff-changed rect,
.svg-hotspot-diff-changed polygon, .svg-hotspot-diff-changed circle,
.svg-hotspot-diff-changed ellipse {
    fill: rgba(184, 134, 11, 0.40) !important;
    stroke: #8a6407 !important;
    stroke-width: 2px !important;
    stroke-dasharray: 1 3 !important;
    stroke-linecap: round !important;
}

.svg-hotspot-diff-added,
.svg-hotspot-diff-removed,
.svg-hotspot-diff-changed {
    opacity: 1 !important;
}

/* Hotspot label text: dark glyph, legible on every one of the three tints. */
text.svg-hotspot-diff-added, tspan.svg-hotspot-diff-added,
.svg-hotspot-diff-added text, .svg-hotspot-diff-added tspan,
text.svg-hotspot-diff-removed, tspan.svg-hotspot-diff-removed,
.svg-hotspot-diff-removed text, .svg-hotspot-diff-removed tspan,
text.svg-hotspot-diff-changed, tspan.svg-hotspot-diff-changed,
.svg-hotspot-diff-changed text, .svg-hotspot-diff-changed tspan {
    fill: #1f1f1f !important;
    stroke: none !important;
}

/* Viewer Container */
.viewer-container {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--white);
    border-radius: 6px;
    overflow: hidden;
}

.viewer-switch-bar {
    background: #f5f5f5;
    border-bottom: 1px solid #e0e0e0;
}

.viewer-switch-btn {
    padding: 6px var(--spacing-lg);
    border: 1px solid var(--gray-400);
    background: var(--white);
    color: var(--gray-600);
    font-size: var(--font-size-sm);
    font-weight: 500;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-base);
}

.viewer-switch-btn:hover {
    background: #f0f0f0;
}

.viewer-switch-btn.viewer-switch-active {
    background: #2e7d32;
    color: var(--white);
    border-color: #2e7d32;
}

.viewer-stack {
    flex: 1;
    overflow: hidden;
}

.viewer-3d-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    background: #fafafa;
}

.viewer-3d-text {
    font-size: var(--font-size-lg);
    color: var(--gray-500);
    font-style: italic;
}

/* ============================================
   HOTSPOT EDITOR
   ============================================ */
.hotspot-editor {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
}
.bom-cart-header-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  flex-wrap: nowrap;
  white-space: nowrap;
}

.bom-tools-header-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  flex-wrap: nowrap;
  white-space: nowrap;
}

.bom-tools-header-wrap .btn-icon,
.bom-cart-header-wrap .btn-icon {
  width: 28px;
  height: 28px;
  padding: 0 !important;
  line-height: 1;
  flex: 0 0 28px;
}

.bom-cart-header-wrap input[type="checkbox"],
.bom-cart-col input[type="checkbox"] {
  margin: 0;
  flex: 0 0 auto;
}
.hotspot-info {
    background: var(--primary-light);
    border: 1px solid #c8e6c9;
    border-radius: 6px;
    padding: var(--spacing-sm) var(--spacing-lg);
    font-size: var(--font-size-sm);
    color: #2e7d32;
}

.hotspot-status {
    padding: var(--spacing-sm) var(--spacing-md);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    margin: var(--spacing-sm) 0;
}

.hotspot-status.success {
    background: #d4edda;
    color: #155724;
    border: 1px solid #c3e6cb;
}

.hotspot-status.error {
    background: #f8d7da;
    color: #721c24;
    border: 1px solid #f5c6cb;
}

.svg-container {
    flex: 1;
    background: #ffffff;
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-lg);
    overflow: auto;
    min-height: 400px;
    padding: var(--spacing-sm);
}

.svg-container svg {
    max-width: 100%;
    height: auto;
}

.svg-container svg [id] {
    cursor: pointer;
    transition: opacity var(--transition-base);
}

.svg-container svg [id]:hover {
    opacity: 0.8;
}

.hotspot-parts-panel {
    background: var(--white);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-lg);
    padding: var(--spacing-lg);
    overflow-y: auto;
    max-height: 500px;
}

.hotspot-parts-panel h4 {
    margin: 0 0 var(--spacing-sm) 0;
    color: var(--gray-800);
    font-size: var(--font-size-base);
    border-bottom: 1px solid var(--gray-200);
    padding-bottom: var(--spacing-sm);
}

.hotspot-part-item {
    cursor: pointer;
    padding: var(--spacing-xs) var(--spacing-sm);
    border-radius: var(--radius-sm);
    display: inline-block;
    transition: background var(--transition-base);
    font-family: var(--font-mono);
    font-size: var(--font-size-sm);
}

.hotspot-part-item:hover {
    background: var(--primary-light);
    color: var(--primary);
}

.hotspot-input {
    width: 100%;
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-base);
}

.hotspot-input:focus {
    border-color: var(--primary);
    outline: none;
    box-shadow: 0 0 0 2px rgba(25, 135, 84, 0.2);
}

.import-preview-table th,
.import-preview-table td {
    padding: var(--spacing-sm);
    border-bottom: 1px solid #e5e7eb;
    text-align: left;
    white-space: nowrap;
}

.import-preview-table th {
    background-color: var(--gray-100);
    font-weight: 600;
}

.status-cell {
    font-size: var(--font-size-sm);
    padding: 6px var(--spacing-sm);
    border-radius: var(--radius-sm);
}

.status-update {
    background-color: #d4edda;
    color: #155724;
    border: 1px solid #c3e6cb;
}

.status-skip {
    background-color: var(--gray-100);
    color: var(--gray-600);
    border: 1px dashed var(--gray-300);
}

/* ============================================
   PART DETAILS DIALOGS
   ============================================ */

.details-section {
    background: var(--gray-100);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-lg);
    padding: var(--spacing-lg);
    margin-bottom: var(--spacing-lg);
}

.details-section h4 {
    margin: 0 0 var(--spacing-sm) 0;
    color: var(--gray-800);
    font-size: var(--font-size-base);
    font-weight: 600;
}

.svg-preview {
    background: var(--white);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
    padding: var(--spacing-sm);
    min-height: 150px;
    max-height: 300px;
    overflow: auto;
}

.svg-preview svg { max-width: 100%; height: auto; }

.csv-textarea {
    width: 100%;
    font-family: var(--font-mono);
    font-size: var(--font-size-sm);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
    padding: var(--spacing-sm);
}

.details-scroll-area {
    max-height: calc(80vh - 120px);
    overflow-y: auto;
}

.details-popup-section {
    background: var(--white);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.section-title {
    background: var(--gray-100);
    padding: var(--spacing-md) var(--spacing-lg);
    font-weight: 600;
    font-size: var(--font-size-base);
    color: var(--gray-800);
    border-bottom: 1px solid var(--gray-300);
}

.svg-display-area {
    padding: var(--spacing-xl);
    min-height: 200px;
    max-height: 400px;
    overflow: auto;
    background: #ffffff;
    display: flex;
    justify-content: center;
    align-items: center;
}

.csv-display-area {
    padding: var(--spacing-lg);
    max-height: 300px;
    overflow: auto;
}

.csv-table th, .csv-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    text-align: left;
    border: 1px solid var(--gray-300);
}

.csv-table tr:first-child td {
    background: var(--gray-100);
    font-weight: 600;
}

.threejs-section { background: #1a1a2e; }
.threejs-section .section-title {
    background: #16213e;
    color: var(--white);
    border-bottom: 1px solid #0f3460;
}

.collapsible-header {
    background: #16213e;
    padding: var(--spacing-md) var(--spacing-lg);
    cursor: pointer;
    color: var(--white);
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
}

.collapsible-header:hover { background: #1a2744; }

.toggle-icon {
    font-size: var(--font-size-sm);
    transition: transform var(--transition-base);
}

.threejs-display-area {
    padding: var(--spacing-xl);
    background: #0f0f23;
}

.threejs-viewer {
    width: 100%;
    height: 400px;
    background: var(--black);
    border-radius: var(--radius-sm);
}

.threejs-info {
    color: var(--gray-500);
    font-size: var(--font-size-sm);
    text-align: center;
    margin-top: var(--spacing-sm);
}

.no-data-message {
    color: var(--gray-600);
    font-style: italic;
    padding: var(--spacing-xl);
    text-align: center;
}

.popup-footer {
    display: flex;
    justify-content: flex-end;
    padding-top: var(--spacing-lg);
    border-top: 1px solid var(--gray-300);
}

/* Right panel column layout */
.threejs-right-panel {
  height: 100%;
  display: flex;
  flex-direction: column;
  border-left: 1px solid rgba(0,0,0,0.08);
  background: rgba(255,255,255,0.85);
}

/* Parts title */
.threejs-parts-title {
  font-weight: 600;
  font-size: calc(14px * var(--font-scale));
  padding: 6px 2px 2px 2px;
}

/* Scroll wrapper */
.threejs-table-wrap {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  border: 1px solid rgba(0,0,0,0.10);
  border-radius: 10px;
  background: #fff;
}

/* Table layout */
.threejs-parts-table {
  width: 100%;
  border-collapse: collapse;
}

/* Sticky header */
.threejs-parts-table .thcell {
  position: sticky;
  top: 0;
  z-index: 2;
  background: #f6f7f9;
  border-bottom: 1px solid rgba(0,0,0,0.10);
  font-weight: 600;
  padding: 8px 10px;
}

/* Body cells */
.threejs-parts-table td {
  padding: 8px 10px;
  border-bottom: 1px solid rgba(0,0,0,0.06);
  vertical-align: middle;
}

/* Row hover */
.threejs-parts-table tr:hover td {
  background: rgba(0,0,0,0.03);
}

/* Column widths */
.threejs-parts-table td:nth-child(1) { width: 36px; }
.threejs-parts-table td:nth-child(3) { width: 80px; }
.threejs-parts-table td:nth-child(4) { width: 44px; }

/* Icon alignment */
.three-eye, .three-addcart {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 28px;
  border-radius: 8px;
}

.clickable { cursor: pointer; }
.clickable:hover { background: rgba(0,0,0,0.06); }

/* Quantity input */
.three-qty input {
  width: 60px;
  padding: 6px 8px;
}
.three-name {
  display: block;
  font-size: calc(13px * var(--font-scale));
}
/* ============================================
   PART IMAGE & THUMBNAIL
   ============================================ */
.part-thumbnail {
    max-width: 60px;
    max-height: 40px;
    object-fit: contain;
    border-radius: var(--radius-sm);
}

.part-thumbnail.clickable {
    cursor: pointer;
    transition: transform var(--transition-base), box-shadow var(--transition-base);
}

.part-thumbnail.clickable:hover {
    transform: scale(1.1);
    box-shadow: 0 2px 8px rgba(0,0,0,0.2);
}

.image-upload-container {
    background: var(--gray-100);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-lg);
    padding: var(--spacing-lg);
}

.image-preview-box {
    width: 100px;
    height: 80px;
    background: var(--white);
    border: 1px dashed var(--gray-300);
    border-radius: var(--radius-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.image-preview {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* Image Popup Dialog */
.image-popup-dialog {
    background: #1a1a1a !important;
    border: none !important;
    border-radius: var(--radius-lg) !important;
    box-shadow: 0 10px 50px rgba(0,0,0,0.5) !important;
    min-width: 200px;
    min-height: 150px;
}

.image-popup-dialog .Wt-dialog-titlebar {
    background: #2a2a2a !important;
    color: var(--white) !important;
    border-bottom: 1px solid #333 !important;
}

.image-popup-container {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: #1a1a1a;
    border-radius: var(--radius-sm);
}

.image-popup-img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* ============================================
   ASSEMBLY HOVER PREVIEW POPOVER
   ============================================ */
#asm-preview-pop {
    position: fixed;
    display: none;
    width: 400px;
    max-width: 92vw;
    height: 400px;
    background: #fff;
    border: 1px solid var(--gray-300);
    border-radius: 8px;
    box-shadow: 0 8px 28px rgba(0,0,0,0.22);
    z-index: 100050;
    overflow: hidden;
    pointer-events: none;
}

#asm-preview-pop .asm-prev-head {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--gray-200);
    background: var(--gray-50, #f8f9fa);
}

#asm-preview-pop .asm-prev-machine {
    font-size: calc(12px * var(--font-scale));
    color: var(--gray-500);
}

#asm-preview-pop .asm-prev-title {
    font-weight: 600;
    font-size: calc(14px * var(--font-scale));
    color: var(--gray-800);
}

#asm-preview-pop .asm-prev-svg {
    display: block;
    width: 100%;
    height: 352px;
    border: none;
    background: #fff;
}

#asm-preview-pop .asm-prev-empty {
    padding: 24px;
    text-align: center;
    color: var(--gray-400);
    font-size: calc(13px * var(--font-scale));
}

/* Column Selector */
.column-selector-dialog .Wt-WCheckBox {
    display: block;
    padding: var(--spacing-sm) 0;
    border-bottom: 1px solid var(--gray-200);
}

/* ============================================
   PART INFO POPUP & SIDEBAR
   ============================================ */
.part-info-dialog { max-width: 550px !important; }

.info-image-container {
    text-align: center;
    margin-bottom: var(--spacing-lg);
    padding: var(--spacing-lg);
    background: var(--gray-100);
    border-radius: var(--radius-lg);
}

.info-image {
    max-width: 100%;
    object-fit: contain;
    border-radius: var(--radius-sm);
}

.info-part-name {
    text-align: center;
    margin-bottom: var(--spacing-lg);
}

.info-part-name h3 {
    margin: 0;
    color: var(--gray-800);
}

.info-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    border-bottom: 1px solid var(--gray-200);
}

.info-table td:first-child {
    font-weight: 600;
    color: var(--gray-600);
    width: 40%;
}

.info-price {
    font-weight: 700;
    color: var(--success);
    font-size: 1.1em;
}

/* Part Info Sidebar */
.part-info-sidebar {
    width: var(--info-panel-width);
    min-width: 250px;
    max-width: 500px;
    height: 100%;
    background: var(--white);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    flex-shrink: 0;
    transition: width 0.25s ease;
}

.part-info-sidebar.collapsed {
    width: 0 !important;
    min-width: 0;
    border-left: none;
}

.part-info-resizer {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 6px;
    background: transparent;
    cursor: col-resize;
    z-index: 10;
}

.part-info-resizer:hover {
    background: var(--primary);
}

.part-info-header {
    background: linear-gradient(135deg, var(--primary-dark) 0%, var(--black) 100%);
    color: var(--white);
    flex-shrink: 0;
    /* See .assembly-tree-header for !important reason. */
    min-height: var(--header-height, 60px) !important;
    height: var(--header-height, 60px) !important;
    padding: 0 var(--spacing-lg);
    display: flex;
    align-items: center;
    box-shadow: 0 2px 8px rgba(0,0,0,0.10);
}

.part-info-title {
    font-weight: 600;
    font-size: var(--font-size-base);
    white-space: nowrap;
}

.part-info-close-btn {
    background: rgba(255,255,255,0.2) !important;
    border: none !important;
    color: var(--white) !important;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm) !important;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 !important;
}

/* Part head block: card with part number + names, favorite star top-right.
   Matches the image/table card look; green accent on the left edge. */
.part-info-headblock {
    background: var(--white);
    border: 1px solid #e0e0e0;
    border-left: 4px solid #198754;
    border-radius: var(--radius-lg);
    padding: 12px 14px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.part-info-head-top { display: flex; align-items: flex-start; gap: 8px; }
.part-info-head-text { flex: 1; min-width: 0; }
.part-info-partnr { font-size: 1.3em; font-weight: 700; color: #198754; letter-spacing: .3px; }
.part-info-partname { color: #495057; margin-top: 4px; line-height: 1.4; font-size: .95em; }

/* Quantity + add-to-cart row inside the head card. */
.part-info-head-cart { border-top: 1px solid #eee; padding-top: 10px; }
/* Second row of the head card: quantity + cart only (Edit and Info sit in
   .part-info-action-row above). The two cells mirror that row -- same gap,
   same 50/50 split -- so the quantity field lines up under Edit and the cart
   button under Info. */
.part-info-cart-row {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    align-items: center;
    gap: 8px;
}

.part-info-qty {
    flex: 1 1 0;
    min-width: 0;
    width: auto !important;
    height: 34px;
    box-sizing: border-box;
    padding: 0 8px;
    text-align: center;
    font-weight: 600;
    color: #212529;
    background: var(--white);
    border: 1px solid var(--primary);
    border-radius: var(--radius-md);
    transition: border-color .15s ease, box-shadow .15s ease;
}

.part-info-qty:hover { border-color: var(--primary-dark); }

/* Brand-green ring, matching the edit-dialog fields. */
.part-info-qty:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 0.2rem rgba(25, 135, 84, 0.25);
}
/* Same surface as Info in the row above; Edit stays the only solid button. */
.part-info-cart-btn {
    flex: 1 1 0;
    min-width: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 34px;
    padding: 0 10px;
    box-sizing: border-box;
    border: 1px solid #dee2e6;
    border-radius: var(--radius-md);
    background: #f0f4f8;
    transition: background .15s ease, border-color .15s ease;
}

.part-info-cart-btn:hover {
    background: #e2e8f0;
    border-color: #ced4da;
}

/* One size for the head-card button glyphs. The links button carries no glyph
   of its own -- its images are the source indicators, sized separately. */
.part-info-head-cart .part-info-edit-btn img,
.part-info-cart-btn img {
    width: 24px !important;
    height: 24px !important;
    object-fit: contain;
    vertical-align: middle;
}

/* Brand-green tint for the icons on the two light buttons; Edit keeps the
   white-on-green treatment from the generic colored-button rule. The leading
   brightness(0) saturate(100%) flattens the source to black first, so the
   result does not depend on each asset's own colour (the cart is a PNG, the
   info icon an SVG). Same idiom as the red tint on .btn-icon-danger. */
.part-info-cart-btn img {
    filter: brightness(0) saturate(100%) invert(38%) sepia(69%) saturate(452%)
            hue-rotate(103deg) brightness(93%) contrast(92%) !important;
}

.part-info-cart-label {
    color: #333;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The wrapper is a flex cell of the row, not an inline island. */
.part-info-cart-row .part-info-cart-btn-wrap {
    flex: 1 1 0;
    min-width: 0;
}

/* Wrapper for the cart button + its transient "added" check badge. */
.part-info-cart-btn-wrap {
    position: relative;
    display: inline-flex;
}
.part-info-cart-added-badge {
    position: absolute;
    top: -6px;
    right: -6px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--success);
    color: var(--white);
    font-size: 12px;
    line-height: 18px;
    text-align: center;
    opacity: 0;
    transform: scale(0.4);
    pointer-events: none;
    transition: opacity .15s ease, transform .15s ease;
}
.part-info-cart-added-badge.show {
    opacity: 1;
    transform: scale(1);
}
.part-info-na-badge {
    display: inline-flex; align-items: center; gap: 6px;
    color: #721c24; background: #f8d7da;
    padding: 6px 12px; border-radius: 4px; font-weight: 600; font-size: .9em;
}
.part-info-deleted-badge {
    display: inline-flex; align-items: center; gap: 6px;
    color: #495057; background: #e2e3e5;
    padding: 6px 12px; border-radius: 4px; font-weight: 600; font-size: .9em;
}

/* Pin toggle in the part-info header; .active = panel survives assembly
   changes (host resets it to the placeholder instead of closing). */
.part-info-pin-btn {
    background: rgba(255,255,255,0.2) !important;
    border: none !important;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm) !important;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 !important;
}
.part-info-pin-btn img { filter: brightness(0) invert(1); width: 15px; height: 15px; }
.part-info-pin-btn.active { background: var(--white) !important; }
.part-info-pin-btn.active img { filter: none; }

.part-info-close-btn:hover {
    background: rgba(255,255,255,0.3) !important;
}

/* Mirrored pin + close inside the head card. Hidden by default (the wide
   layout uses the header pair); the portrait media query reveals them. Styled
   for the light card: muted dark icons. */
.part-info-card-pin,
.part-info-card-close {
    display: none !important;   /* shown only in portrait (media query) */
    background: transparent !important;
    border: none !important;
    color: #888 !important;
    width: 26px;
    height: 26px;
    border-radius: var(--radius-sm) !important;
    cursor: pointer;
    align-items: center;
    justify-content: center;
    padding: 0 !important;
    font-size: calc(15px * var(--font-scale));
    line-height: 1;
    flex: 0 0 auto;
}
.part-info-card-pin img { filter: brightness(0) opacity(0.55); width: 15px; height: 15px; }
.part-info-card-pin.active { background: #198754 !important; }
.part-info-card-pin.active img { filter: brightness(0) invert(1); }
.part-info-card-pin:hover,
.part-info-card-close:hover { background: #eee !important; }

.part-info-edit-btn {
    background: var(--primary) !important;
    border: none !important;
    color: var(--white) !important;
    height: 36px;
    min-height: 36px;
    border-radius: var(--radius-md) !important;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 0 14px !important;
    font-weight: 600;
    white-space: nowrap;
    width: 100%;
    box-sizing: border-box;
}

.part-info-edit-btn:hover {
    background: var(--primary-dark) !important;
}

/* Edit inside the head card is compact, not the full-width form button. Sizing
   only; placement comes from .part-info-action-row below. */
.part-info-head-cart .part-info-edit-btn {
    width: auto;
    height: 32px;
    min-height: 32px;
    flex: 0 0 auto;
}

/* Second cell of the action row: the links group. Sized like the button it
   replaced so the two rows of the head card stay aligned. */
.part-info-link-inds {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 36px;
    padding: 0 6px;
    box-sizing: border-box;
    border: 1px solid #dee2e6;
    border-radius: var(--radius-md);
    background: #f0f4f8;
    overflow: hidden;
}

.part-info-link-ind {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 2px 4px;
    border-radius: var(--radius-md);
    color: #495057;
    font-size: var(--font-size-sm);
    font-weight: 700;
    cursor: pointer;
    white-space: nowrap;
}

.part-info-link-ind:hover {
    background: #dceaf7;
}

/* assembly / file / history. `box` is the 3D view elsewhere and `bom-expand`
   carries a down chevron that reads as an expander, so the assembly glyph is
   its own asset: stacked layers, i.e. parts composed into one. */
.part-info-link-ind img {
    width: 15px !important;
    height: 15px !important;
    object-fit: contain;
    filter: brightness(0) saturate(100%) invert(38%) sepia(69%) saturate(452%)
            hue-rotate(103deg) brightness(93%) contrast(92%);
}

/* Head-card control geometry, authoritative for all four cells. Edit, Info,
   the quantity field and Add are declared in separate rules above with
   different heights, paddings and border widths, which left the two rows
   visibly out of line. One box definition here keeps their edges flush. */
.part-info-head-cart .part-info-edit-btn,
.part-info-head-cart .part-info-link-inds,
.part-info-head-cart .part-info-qty,
.part-info-head-cart .part-info-cart-btn {
    /* Labels are nowrap, so a long translation would spill out of its grid
       column; clipped here rather than left to each locale's word length. */
    overflow: hidden !important;
    height: 36px !important;
    min-height: 36px !important;
    padding: 0 10px !important;
    box-sizing: border-box !important;
    border-style: solid !important;
    border-width: 1px !important;
    border-radius: var(--radius-md) !important;
}

/* Edit carries no visible border; a transparent one keeps its box identical
   to the bordered cells so the text sits on the same baseline. */
.part-info-head-cart .part-info-edit-btn {
    border-color: transparent !important;
}

/* Grid items fill their own column; the intrinsic width of an <input> and of
   an icon+label button must not leak into the track sizing. */
.part-info-action-row .part-info-edit-btn,
.part-info-action-row .part-info-link-inds,
.part-info-cart-row .part-info-qty,
.part-info-cart-row .part-info-cart-btn-wrap {
    width: 100% !important;
    min-width: 0 !important;
}

.part-info-cart-row .part-info-cart-btn {
    width: 100% !important;
}

/* Head card actions: Edit + Info share one row above the quantity + cart row.
   The four controls cannot fit a single line at the sidebar's width. Both
   buttons stretch so the pair reads as one deliberate block. */
/* Grid, not flex: `minmax(0, 1fr)` columns are exactly equal regardless of
   what each cell contains, so the icon+label of Add can never claim more room
   than the quantity field. The cart row below uses the same template, which is
   what keeps the two rows' edges flush. */
.part-info-action-row {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
}

.part-info-action-row .part-info-edit-btn {
    order: 0;
    margin-right: 0;
    width: auto;
    min-width: 0;
}

.part-info-content {
    flex: 1;
    /* A column flex child defaults to min-height:auto and refuses to shrink
       below its content, which makes overflow-y inert and leaves the last
       rows unreachable. */
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    background: #fafafa;
    display: flex;
    flex-direction: column;
    gap: 15px;
    padding: 15px 15px 24px;
}
/* Fixed-size blocks: never shrink, so button/head-card keep the same height
   and position no matter the content; overflow scrolls instead. */
.part-info-content > * { flex: 0 0 auto; }

.part-info-image-container {
    background: var(--white);
    border: 1px solid #e0e0e0;
    border-radius: var(--radius-lg);
    padding: var(--spacing-lg);
    text-align: center;
}
/* No-image spacer: keeps layout spacing without rendering an empty card. */
.part-info-image-container.image-empty {
    background: transparent;
    border: none;
    padding: 0;
    height: 0;
    min-height: 0;
    overflow: hidden;
}

.part-info-image {
    max-width: 100%;
    max-height: 180px;
    object-fit: contain;
    border-radius: var(--radius-sm);
}

.part-info-table {
    background: var(--white);
    border: 1px solid #e0e0e0;
    border-radius: var(--radius-lg);
    border-collapse: separate;
    border-spacing: 0;
    overflow: hidden;
}

.part-info-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    border-bottom: 1px solid #f0f0f0;
    vertical-align: top;
}

.part-info-table tr:last-child td { border-bottom: none; }

.part-info-table .info-label {
    font-weight: 600;
    color: var(--gray-600);
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    width: 35%;
    background: var(--gray-100);
}

.part-info-table .info-value {
    color: var(--gray-800);
    font-size: var(--font-size-sm);
}

.part-info-table .info-part-number {
    font-family: var(--font-mono);
    font-weight: 600;
    color: var(--primary);
}

.part-info-table .info-price {
    font-weight: 700;
    color: var(--success);
    font-size: var(--font-size-lg);
}

.part-info-empty {
    color: var(--gray-500);
    font-style: italic;
    text-align: center;
    padding: 40px var(--spacing-xl);
}

/* ============================================
   SEARCH PAGE
   ============================================ */
/* Search page flows as a normal block; scrolling is handled by the
   content container (overflow-y:auto set in showSearchPage). */
.search-page {
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

/* In-page search bar at the top of the full results page */
.search-page-bar {
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: 480px;
}

.search-page-input {
    flex: 1 1 auto;
    min-width: 0;
    height: 36px !important;
    padding: 0 12px !important;
    border: 1.5px solid var(--primary) !important;
    border-radius: 6px !important;
    font-size: calc(14px * var(--font-scale)) !important;
    box-sizing: border-box !important;
    margin: 0 !important;
}

.search-page-input:focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.15);
}

/* Master-data articles that no parts list contains (internal users). */
.search-articles-title {
    margin: var(--spacing-lg) 0 var(--spacing-sm);
    color: var(--gray-700);
    font-size: calc(13px * var(--font-scale));
    font-weight: 700;
}

.search-section {
    background: var(--white);
    border-radius: var(--radius-lg);
    padding: var(--spacing-lg);
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.search-section h3 {
    margin: 0 0 var(--spacing-lg) 0;
    color: var(--gray-800);
    border-bottom: 2px solid #007bff;
    padding-bottom: var(--spacing-sm);
}

.search-table th, .search-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    text-align: left;
    border-bottom: 1px solid var(--gray-200);
}

.search-table th {
    background: var(--gray-100);
    font-weight: 600;
}

.search-table tr:hover td { background: #f0f7ff; }

.search-link { color: #007bff; font-weight: 500; }

.search-row-click { cursor: pointer; }
.search-row-click:hover { background: #e8f4ff !important; }

/* Machine filter chip bar — sits between the query line and results */
.machine-chip-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 6px 0;
}

button.machine-chip,
.machine-chip {
    padding: 5px 14px;
    border: 1px solid var(--gray-400);
    border-radius: 20px;
    background: var(--gray-100);
    color: var(--gray-800);
    font-size: var(--font-size-sm);
    font-weight: 500;
    cursor: pointer;
    margin: 0;
    line-height: 1.3;
    text-align: center;
    text-decoration: none;
    box-shadow: none;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
}

button.machine-chip:hover,
.machine-chip:hover {
    border-color: var(--primary);
    color: var(--primary);
    background: var(--primary-light, #e8f5e9);
}

button.machine-chip-active,
.machine-chip-active,
.machine-chip-active:hover {
    background: var(--primary) !important;
    color: var(--white) !important;
    border-color: var(--primary) !important;
    font-weight: 600 !important;
}

/* ============================================
   VISIBILITY SELECTOR
   ============================================ */
.vis-row-btn {
    background: #dddddd;
    border: 1px solid #aaaaaa;
    padding: var(--spacing-xs) 6px;
    min-width: 30px;
    cursor: pointer;
    border-radius: var(--radius-sm);
}

.vis-cell {
    background: #eeeeee;
    border: 1px solid #bbbbbb;
    padding: var(--spacing-xs);
    min-width: 35px;
    text-align: center;
    cursor: pointer;
    border-radius: var(--radius-sm);
}

.vis-cell.vis-cell-selected {
    border-color: #2f7cff;
    background: #dce9ff;
    font-weight: bold;
}

/* Rule chips + matching-machines preview (visibility tab). */
.vis-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    min-height: 24px;
}
.vis-chip {
    display: inline-flex;
    align-items: center;
    background: #e7f1ff;
    border: 1px solid #2f7cff;
    color: #1b4fa0;
    border-radius: 12px;
    padding: 2px 10px;
    font-size: var(--font-size-sm);
    font-weight: 600;
}
.vis-chip-x {
    cursor: pointer;
    color: #1b4fa0;
    font-weight: 700;
}
.vis-chip-x:hover { color: #c0392b; }
.vis-hint {
    font-size: var(--font-size-xs);
    color: var(--gray-600);
}
.vis-preview-label {
    font-weight: 600;
    color: var(--gray-700);
    margin-top: 4px;
}
.vis-preview {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 6px;
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-sm);
}

/* ============================================
   SHOPPING CART
   ============================================ */
.shopping-cart-container {
    padding: var(--spacing-lg);
    height: 100%;
    overflow-y: auto;
}

.cart-toolbar {
    background: var(--gray-100);
    padding: var(--spacing-sm) var(--spacing-lg);
    border-radius: 6px;
    margin-bottom: var(--spacing-sm);
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

.cart-toolbar > * {
    flex: 0 0 auto;
}

.cart-selector-dropdown, .cart-selector-dropdown-small {
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-base);
    background: var(--white);
}

.cart-selector-dropdown { width: 100%; }
.cart-selector-dropdown-small { width: 180px; }

.btn-cart-action {
    padding: 6px var(--spacing-md);
    border: none;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    cursor: pointer;
}

.btn-new-cart { background-color: #2e7d32; color: var(--white); }
.btn-new-cart:hover { background-color: #45a049; }
.btn-rename-cart { background-color: #2196F3; color: var(--white); }
.btn-rename-cart:hover { background-color: #1976D2; }
.btn-delete-cart { background-color: #f44336; color: var(--white); }
.btn-delete-cart:hover { background-color: #d32f2f; }
.btn-send-order { background-color: #FF9800; color: var(--white); font-weight: bold; }
.btn-send-order:hover { background-color: #F57C00; }

.btn-cart-icon {
    background: none;
    border: none;
    font-size: var(--font-size-xl);
    cursor: pointer;
    padding: 6px var(--spacing-sm);
    border-radius: var(--radius-sm);
}

.btn-cart-icon:hover { background: rgba(0, 0, 0, 0.05); }
.btn-cart-icon-danger:hover { background: rgba(244, 67, 54, 0.1); }

.cart-total-text {
    font-size: var(--font-size-base);
    font-weight: bold;
    color: var(--gray-800);
    margin-bottom: var(--spacing-sm);
}

.cart-items-container { flex: 1; overflow-y: auto; }

.cart-empty-text {
    color: var(--gray-500);
    font-style: italic;
    text-align: center;
    padding: var(--spacing-xl);
}

.cart-machine-group {
    margin-bottom: var(--spacing-lg);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
}

.cart-items-table th, .cart-items-table td {
    padding: var(--spacing-sm);
    text-align: left;
    border-bottom: 1px solid var(--gray-200);
}

.cart-items-table th {
    background-color: #f9f9f9;
    font-weight: 600;
    font-size: var(--font-size-sm);
    color: var(--gray-600);
}

.cart-bottom-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    background: var(--gray-100);
    padding: var(--spacing-lg);
    border-radius: 6px;
    border-top: 2px solid var(--primary);
}

.cart-bottom-bar .cart-total-price,
.cart-bottom-bar .cart-total-weight {
    margin-right: var(--spacing-md);
}

.cart-bottom-bar .cart-total-price:first-child {
    margin-right: var(--spacing-sm);
}

.cart-bottom-bar .cart-total-weight {
    margin-right: auto;
}

.cart-totals-container { display: flex; align-items: center; }
.cart-total-weight { font-size: var(--font-size-lg); font-weight: 600; color: var(--gray-600); }
.cart-total-price { font-size: var(--font-size-lg); font-weight: 700; color: var(--primary); }

.cart-cell-image { width: 50px; text-align: center; }
.cart-part-thumbnail { max-width: 45px; max-height: 35px; object-fit: contain; border-radius: 3px; }
.cart-cell-right { text-align: right !important; }
.cart-cell-quantity { width: 120px; white-space: nowrap; }
.cart-quantity-spinner { width: 60px; display: inline-block; vertical-align: middle; }

.btn-qty-save {
    background: transparent;
    border: none;
    font-size: var(--font-size-lg);
    cursor: pointer;
    padding: 2px 6px;
    margin-left: var(--spacing-xs);
}

.btn-qty-save:hover { opacity: 0.7; }
.btn-qty-hidden { visibility: hidden; }

.btn-cart-save-qty {
    background: #2196F3;
    color: var(--white);
    border: none;
    border-radius: var(--radius-sm);
    padding: var(--spacing-xs) var(--spacing-sm);
    font-size: var(--font-size-base);
    cursor: pointer;
    margin-left: var(--spacing-sm);
}

.btn-cart-save-qty:hover { background: #1976D2; }

.cart-cell-actions { width: 80px; }

.btn-cart-item-delete {
    background: none;
    border: none;
    cursor: pointer;
    padding: var(--spacing-xs);
    opacity: 0.6;
}

.btn-cart-item-delete:hover { opacity: 1; }

.cart-dialog { min-width: 350px; }
.cart-dialog-content { padding: var(--spacing-xl); }

.cart-row-deleted {
    background: #fff1f2 !important;
    color: var(--gray-500);
}
.cart-row-deleted td { background: transparent !important; }
.cart-deleted-badge {
    display: inline-flex;
    width: fit-content;
    margin-top: 5px;
    padding: 2px 7px;
    border: 1px solid #dc3545;
    border-radius: 999px;
    color: #b42318;
    background: #fff;
    font-size: var(--font-size-xs);
    font-weight: 600;
}

.cart-name-input, .cart-notes-input {
    width: 100%;
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
    margin-top: var(--spacing-sm);
    margin-bottom: var(--spacing-lg);
}

.cart-notes-input { resize: vertical; }
.send-order-dialog {
    min-width: 450px;
    max-height: min(88dvh, 760px) !important;
}
.send-order-dialog .Wt-dialog-contents,
.send-order-dialog .contents {
    max-height: calc(min(88dvh, 760px) - 52px);
    overflow-y: auto !important;
    overscroll-behavior: contain;
}
.send-order-dialog .cart-dialog-content {
    box-sizing: border-box;
    padding: var(--spacing-lg);
}
.send-order-dialog .checkout-items {
    max-height: min(34dvh, 300px);
    overflow-y: auto;
    padding-right: var(--spacing-xs);
}
.send-order-dialog .dialog-section-title,
.send-order-dialog .dialog-field-label,
.send-order-dialog .guest-order-error {
    display: block;
    clear: both;
}
.send-order-dialog .checkout-address-toggle {
    display: block !important;
    width: fit-content !important;
    margin: 8px 0 12px !important;
}
.send-order-dialog .checkout-address-form {
    padding: 12px;
    margin: 0 0 14px;
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-sm);
    background: var(--gray-100);
}
.send-order-dialog .checkout-address-form .dialog-field-label {
    margin-top: 8px;
}
.send-order-dialog .checkout-address-form .dialog-field-label:first-child {
    margin-top: 0;
}
.send-order-dialog .checkout-notes-label { margin-top: 14px; }
.send-order-dialog .checkout-notes-input { margin-bottom: 14px; }
.send-order-dialog .dialog-input-full { box-sizing: border-box; }
.send-order-dialog .checkout-dialog-buttons {
    position: static !important;
    clear: both;
    margin-top: 4px;
    padding-top: 12px;
    border-top: 1px solid var(--gray-200);
}

/* Guest checkout dialog (order via email) */
.guest-order-summary { margin-top: var(--spacing-sm); }
.guest-order-summary-line {
    display: block;
    padding: var(--spacing-xs) 0;
    border-bottom: 1px solid var(--gray-200);
    font-size: var(--font-size-sm);
}
.guest-order-summary-total {
    display: block;
    margin-top: var(--spacing-sm);
    font-weight: 700;
}
.guest-order-error {
    display: block;
    color: var(--danger);
    margin-top: var(--spacing-sm);
}

/* ---- Guest checkout wizard ---- */
.guest-checkout-dialog .checkout-steps {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-lg);
    margin: var(--spacing-xs) 0 var(--spacing-lg);
    flex-wrap: wrap;
}
.checkout-step {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--gray-400);
    font-size: var(--font-size-sm);
    font-weight: 600;
}
.checkout-step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--gray-200);
    color: var(--gray-500);
    font-size: calc(13px * var(--font-scale));
    font-weight: 700;
}
.checkout-step.active { color: var(--primary); }
.checkout-step.active .checkout-step-num { background: var(--primary); color: var(--white); }
.checkout-step.done { color: var(--primary); }
.checkout-step.done .checkout-step-num { background: var(--primary-dark, var(--primary)); color: var(--white); }

.checkout-items { margin-bottom: var(--spacing-sm); }
.checkout-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-md);
    padding: var(--spacing-sm) 0;
    border-bottom: 1px solid var(--gray-200);
}
.checkout-item-info { display: flex; flex-direction: column; min-width: 0; }
.checkout-item-name { font-weight: 600; color: var(--gray-800); }
.checkout-item-sub { font-size: var(--font-size-sm); color: var(--gray-400); }
.checkout-item-right { display: flex; align-items: center; gap: var(--spacing-md); flex: 0 0 auto; }
.checkout-item-qty { color: var(--gray-500); font-size: var(--font-size-sm); }
.checkout-item-total { font-weight: 700; color: var(--gray-800); white-space: nowrap; }

.checkout-total-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-top: var(--spacing-sm);
    padding-top: var(--spacing-sm);
    border-top: 2px solid var(--gray-200);
}
.checkout-total-label { font-weight: 600; color: var(--gray-600); }
.checkout-total-value { font-weight: 800; font-size: var(--font-size-lg); color: var(--primary); }

.checkout-review {
    background: var(--gray-100, #f5f5f5);
    border-radius: var(--radius-sm);
    padding: var(--spacing-sm) var(--spacing-md);
    margin-bottom: var(--spacing-sm);
}
.checkout-review-line { display: block; line-height: 1.5; color: var(--gray-800); }
.checkout-payment-note {
    display: block;
    color: var(--gray-600);
    font-size: var(--font-size-sm);
    background: var(--gray-100, #f5f5f5);
    border-left: 3px solid var(--primary);
    border-radius: var(--radius-sm);
    padding: var(--spacing-sm) var(--spacing-md);
    margin-bottom: var(--spacing-md);
}

/* ============================================
   ORDER MANAGEMENT
   ============================================ */
.order-management-container {
    height: 100%;
    display: flex;
    flex-direction: column;
}

.order-top-bar {
    background: var(--gray-100);
    padding: var(--spacing-sm) var(--spacing-lg);
    border-radius: 6px;
    margin-bottom: var(--spacing-sm);
    border: 1px solid #e0e0e0;
}

.order-page-title {
    font-size: var(--font-size-xl);
    font-weight: 600;
    color: var(--gray-800);
    margin-left: var(--spacing-lg);
}

.order-tab-bar {
    display: flex;
    flex-direction: row;
    gap: 0;
    border-bottom: 2px solid var(--primary);
    background: var(--gray-100);
    flex-shrink: 0;
}

.order-tab-btn {
    display: block;
    padding: var(--spacing-md) var(--spacing-2xl);
    font-size: var(--font-size-base);
    font-weight: 500;
    background: transparent;
    color: var(--gray-600);
    cursor: pointer;
    border: none;
    border-bottom: 3px solid transparent;
    margin-bottom: -2px;
    outline: none;
    box-shadow: none;
}

.order-tab-btn:hover {
    background: var(--primary-light);
    color: var(--primary);
}

.order-tab-btn.active {
    background: var(--white);
    color: var(--primary);
    font-weight: 600;
    border-bottom-color: var(--primary);
}

.order-tab-stack {
    border: 1px solid var(--gray-300) !important;
    border-top: none !important;
    background: var(--white) !important;
    overflow: auto !important;
    min-height: 400px !important;
}

.order-tab-content {
    padding: var(--spacing-lg);
    background: var(--white);
    min-height: 300px;
}

.orders-empty-text {
    display: block;
    text-align: center;
    padding: 40px var(--spacing-xl);
    color: var(--gray-500);
    font-style: italic;
    font-size: var(--font-size-lg);
}

.order-table th, .order-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    text-align: left;
    border-bottom: 1px solid #e0e0e0;
    vertical-align: middle;
}

.order-table th {
    background: #f5f5f5;
    font-weight: 600;
    border-bottom: 2px solid var(--gray-300);
}

.order-table tr:hover td { background: var(--gray-100); }
.order-table tr:nth-child(even) td { background-color: #fafafa; }

.btn-order-link {
    background: none !important;
    border: none !important;
    color: var(--info) !important;
    cursor: pointer;
    font-weight: 600;
    text-decoration: underline;
    padding: 0 !important;
}

.btn-order-link:hover { color: #0a58ca !important; }

.order-status {
    padding: var(--spacing-sm) var(--spacing-md);
    border-radius: 20px;
    font-size: var(--font-size-xs);
    font-weight: 600;
    display: inline-block;
    text-transform: uppercase;
}

.status-pending { background-color: #FFF3E0; color: #E65100; border: 1px solid #FFB74D; }
.status-processing { background-color: #E3F2FD; color: #1565C0; border: 1px solid #64B5F6; }
.status-completed { background-color: var(--primary-light); color: #2E7D32; border: 1px solid #81C784; }
.status-cancelled { background-color: #FFEBEE; color: #C62828; border: 1px solid #E57373; }

.order-actions-cell { min-width: 200px; white-space: nowrap; }

/* .order-tab-stack already has overflow:auto (unconditional, above), but a
   width:100% table never triggers it. Give the table a min-width so its
   5 columns scroll instead of crushing once .order-actions-cell can shrink
   (mobile override in the MOBILE DIALOG CONTRACT block). */
@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
    .order-tab-stack {
        -webkit-overflow-scrolling: touch;
    }

    .order-table {
        min-width: 520px !important;
    }
}

.btn-order-action {
    padding: var(--spacing-xs) var(--spacing-md);
    border: none;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    font-weight: 500;
    cursor: pointer;
}

.btn-process { background-color: #2196F3; color: var(--white); }
.btn-process:hover { background-color: #1976D2; }
.btn-complete { background-color: #4CAF50; color: var(--white); }
.btn-complete:hover { background-color: #388E3C; }

.order-details-dialog { min-width: min(600px, 95vw); }

.order-details-content {
    padding: var(--spacing-lg);
    max-height: 70vh;
    overflow-y: auto;
}

.order-info-box, .order-items-box { margin-bottom: var(--spacing-xl); }

.order-info-box legend, .order-items-box legend,
.order-section-title {
    font-weight: 600;
    color: var(--primary);
    font-size: var(--font-size-lg);
}

.order-section-title {
    display: block;
    margin-bottom: var(--spacing-md);
}

.order-info-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    border-bottom: 1px solid var(--gray-200);
}

.order-info-table td:first-child {
    font-weight: 600;
    color: var(--gray-600);
    width: 140px;
}

.order-machine-header {
    font-weight: 600;
    font-size: var(--font-size-base);
    color: var(--primary);
    margin: var(--spacing-lg) 0 var(--spacing-sm) 0;
    padding: var(--spacing-sm) var(--spacing-md);
    background: var(--primary-light);
    border-radius: var(--radius-sm);
}

.order-items-table th, .order-items-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    text-align: left;
    border-bottom: 1px solid var(--gray-200);
}

.order-items-table th {
    background-color: var(--gray-100);
    font-weight: 600;
    color: var(--gray-600);
}

/* Large Dialog */
.large-dialog { max-width: 95% !important; }

@media (min-width: 1200px) {
    .large-dialog .Wt-dialog { width: 1100px !important; max-width: 1100px !important; }
}

/* Global mobile cap: no dialog may exceed the phone screen regardless of its
   setWidth(px); oversized content scrolls inside instead of overflowing the
   page. Applies to every Wt dialog (all carry the .Wt-dialog class). */
@media (max-width: 768px) {
    .Wt-dialog {
        max-width: 96vw !important;
        max-height: 94vh !important;
    }
    .Wt-dialog .Wt-dialog-body,
    .Wt-dialog .body,
    .Wt-dialog .Wt-dialog-contents {
        max-height: 80vh;
        overflow: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* Order export dialog — full-width controls on small screens. */
@media (max-width: 480px) {
    .export-dialog-section { margin-bottom: 10px; }
    .export-combo { width: 100%; min-width: 0 !important; max-width: 100%; }
    .export-col-list { max-height: 200px; overflow-y: auto; }
    .export-option-row { flex-wrap: wrap; }
}

/* ============================================
   ORDER EXPORT DIALOG — column picker redesign
   ============================================ */
.export-dialog-section { margin-bottom: 14px; }
.export-dialog-section > .export-section-title {
    display: block;
    font-weight: 600;
    font-size: var(--font-size-sm);
    color: var(--gray-600);
    margin-bottom: 6px;
}

.export-combo {
    display: inline-block;
    min-width: 160px;
    padding: 6px 10px;
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
    background: var(--white);
    color: var(--gray-800);
    font-size: var(--font-size-base);
    cursor: pointer;
}

.export-col-list {
    border: 1px solid var(--gray-200);
    border-radius: 6px;
    max-height: 320px;
    overflow-y: auto;
}

.export-col-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 12px;
    border-bottom: 1px solid var(--gray-100);
}

.export-col-row:last-child { border-bottom: none; }
.export-col-row:hover { background: var(--gray-100); }

.export-col-label {
    flex: 1;
    font-size: var(--font-size-sm);
}

.export-col-btn {
    width: 26px;
    height: 26px;
    padding: 0;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--gray-300);
    border-radius: 4px;
    background: #fff;
    cursor: pointer;
    font-size: var(--font-size-xs);
    flex-shrink: 0;
}

.export-col-btn:hover { background: var(--gray-200); }

/* BOM column selector: let the checkbox+label grow so up/down sit at the right. */
.export-col-row .bom-selcol-cb { flex: 1; }

/* SVG chevron icons for up/down reorder buttons */
.export-col-up {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 5l4 6H4z' fill='%23555'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 12px 12px;
}
.export-col-down {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 11L4 5h8z' fill='%23555'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 12px 12px;
}

/* ============================================
   RESPONSIVE - TABLET (max-width: 1024px)
   ============================================ */
@media only screen and (max-width: 1024px) {
    :root {
        --sidebar-width: 240px;
        --info-panel-width: 280px;
    }

    .machine-page-layout {
        height: calc(100vh - 110px);
    }

    .panel-center {
        min-width: 300px;
    }

    .assembly-bar-name {
        font-size: var(--font-size-base);
    }

    .assembly-bar-note-inline {
        display: none;
    }

    .bom-table th, .bom-table td {
        padding: var(--spacing-sm);
        font-size: var(--font-size-sm);
    }

    .edit-dialog {
        width: 90vw;
        max-width: 95vw;
    }

    .import-price-dialog {
        width: 90vw;
        height: 80vh;
    }
}
.panel-left,
.panel-center,
.center-content-area,
#centerContentArea,
#viewer-wrapper,
#bom-wrapper,
.part-info-sidebar,
.part-info-content,
.assembly-tree,
.assembly-tree-content {
  min-height: 0;
}
/* ============================================
   RESPONSIVE - TABLET PORTRAIT (max-width: 768px)
   ============================================ */
@media only screen and (max-width: 768px) {
    :root {
        --sidebar-width: 220px;
        --sidebar-min: 40px;
        --info-panel-width: 60vw;
        --header-height: 40px;
    }

    .assembly-viewer.assembly-viewer-capped {
        height: auto;
    }

    /* Login */
    .login-box {
        width: 95%;
        padding: var(--spacing-xl) var(--spacing-lg);
    }

    .login-logo {
        max-width: 150px;
    }

    /* Navigation */
    .machine-dropdown {
        min-width: 150px;
        font-size: var(--font-size-sm);
    }

    .search-input {
        width: 130px;
    }

    .nav-icon-btn {
        padding: var(--spacing-sm) var(--spacing-md);
        font-size: var(--font-size-lg);
    }

    .machine-page-layout {
      display: flex;
      width: 100%;
      height: 100%;
      min-height: 0;
      overflow: hidden;
      background: #f5f5f5;
    }
    .content-container {
      display: flex;
      flex-direction: column;
      flex: 1 1 auto;
      min-height: 0;
      overflow: hidden;
    }

    .content-container > .machine-page-layout {
      flex: 1 1 auto;
      min-height: 0;
    }

    /* panel-left sizing is handled by the overlay drawer rules further
       below (position:fixed, 50vw x 100vh). No legacy max-height cap here
       or the drawer gets clipped to a small strip. */

    .machine-page-layout .panel-center {
        min-width: 100%;
        height: auto;
        flex: 1;
    }

.vertical-resizer {
    margin-top: var(--header-height);
    height: calc(100% - var(--header-height));
    align-self: flex-start;
    background: transparent;
    position: relative
}

.vertical-resizer::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 44px;
    background: linear-gradient(135deg, #198754 0%, #0f5132 100%);
}

/* Left resizer */
#left-resizer::before {
    background: linear-gradient(135deg, #198754 0%, #0f5132 100%);
}

/* Right resizer */
#right-resizer::before {
    background: linear-gradient(135deg, #0f5132 0%, #000000 100%);
}
#left-resizer,
#right-resizer {
    margin-top: 44px;
    height: calc(100% - 44px);
}


    /* Assembly Bar */
    .assembly-bar-top {
        flex-wrap: nowrap;
        padding: var(--spacing-sm);
        gap: var(--spacing-sm);
    }

    .assembly-bar-left {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--spacing-xs);
    }

    .assembly-bar-name {
        max-width: 100%;
    }

    .assembly-bar-code {
        font-size: var(--font-size-lg);
    }

    .assembly-bar-version {
        width: 100%;
    }

    /* BOM Table — every column shrinks to its own content here; no px floors
       are added, so the table fits until the content itself stops fitting.
       Columns are never hidden: visibility is the user's choice via the
       column selector. Horizontal scroll is the last resort, handled by
       .bom-table-wrapper { overflow: auto }. */
    .bom-viewer-container {
        max-height: none;
        resize: none;
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    .bom-table {
        font-size: var(--font-size-sm);
        min-width: 480px;
    }

    .bom-table th,
    .bom-table td {
        padding: 6px 8px !important;
    }

    .bom-table .bom-image-col {
        width: calc(56px * var(--font-scale));
    }

    /* Viewer */
    .viewer-wrapper {
        min-height: 200px;
    }

    /* Dialogs */
    .Wt-dialog {
        width: 95vw !important;
        max-width: 95vw !important;
        margin: var(--spacing-sm) !important;
    }

    .edit-dialog,
    .order-details-dialog {
        max-width: 95vw !important;
    }

    /* Forms */
    .edit-input {
        min-width: 100%;
    }

    /* Tables */
    .edit-parts-table, .edit-price-table, .order-table {
        font-size: var(--font-size-sm);
    }

    /* Cart */
    .cart-toolbar {
        flex-wrap: wrap;
    }

    .cart-selector-dropdown-small {
        width: 100%;
    }

    /* Order Tabs */
    .order-tab-btn {
        padding: var(--spacing-sm) var(--spacing-md);
        font-size: var(--font-size-sm);
    }
}

/* ============================================
   RESPONSIVE - MOBILE (max-width: 480px)
   ============================================ */
@media only screen and (max-width: 480px) {
    :root {
        --font-size-base: calc(13px * var(--font-scale));
        --spacing-lg: 12px;
        --spacing-xl: 16px;
    }

    .assembly-viewer.assembly-viewer-capped {
        height: auto;
    }

    /* Login */
    .login-logo {
        max-width: 120px;
        margin-bottom: var(--spacing-xl);
    }

    .login-box {
        padding: var(--spacing-xl) var(--spacing-md);
    }

    .login-title h2 {
        font-size: var(--font-size-xl);
    }

    /* Navigation */
    .machine-dropdown {
        min-width: 100px;
        font-size: var(--font-size-xs);
        padding: 6px var(--spacing-sm);
    }

    .search-input {
        width: 100px;
        font-size: var(--font-size-sm);
    }

    .nav-icon-btn {
        padding: 6px var(--spacing-sm);
        font-size: var(--font-size-base);
    }

    .user-dropdown-btn {
        padding: 6px var(--spacing-sm);
        font-size: var(--font-size-sm);
    }

    /* Assembly Bar */
    .assembly-bar-code {
        font-size: var(--font-size-base);
    }

    .assembly-bar-name {
        font-size: var(--font-size-sm);
    }

    .assembly-bar-version label {
        display: none;
    }

    /* Assembly Tree */
    .assembly-tree-header-title {
        font-size: var(--font-size-sm);
    }

    .assembly-tree-name {
        font-size: var(--font-size-xs);
    }

    .assembly-tree-code {
        font-size: calc(10px * var(--font-scale));
    }

    /* BOM Table - smaller type lets the same column set fit a phone width. */
    .bom-table {
        font-size: var(--font-size-xs);
        min-width: 420px;
    }

    /* Buttons */
    .btn, .btn-primary, .btn-secondary {
        padding: var(--spacing-sm) var(--spacing-md) !important;
        font-size: var(--font-size-sm) !important;
        min-width: 80px !important;
    }

    /* Dialogs */
    .Wt-dialog .titlebar,
    .Wt-dialog .Wt-dialog-title-bar {
        padding: var(--spacing-sm) var(--spacing-md) !important;
        font-size: var(--font-size-base) !important;
    }

    .Wt-dialog .body,
    .Wt-dialog .Wt-dialog-body {
        padding: var(--spacing-md) !important;
    }

    /* Tables - Scroll */
    .parts-table-container,
    .price-table-container,
    .bom-table-wrapper {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Part Info Sidebar */
    .part-info-table .info-label {
        font-size: calc(10px * var(--font-scale));
        width: 40%;
    }

    .part-info-image {
        max-height: 120px;
    }

    /* Cart */
    .cart-items-table th, .cart-items-table td {
        padding: var(--spacing-xs);
        font-size: var(--font-size-xs);
    }

    .cart-part-thumbnail {
        max-width: 35px;
        max-height: 25px;
    }

    .cart-quantity-spinner {
        width: 50px;
    }

    /* Order */
    .order-table th, .order-table td {
        padding: var(--spacing-xs);
        font-size: var(--font-size-xs);
    }

    .order-status {
        padding: var(--spacing-xs) var(--spacing-sm);
        font-size: calc(10px * var(--font-scale));
    }

    .order-actions {
        flex-direction: column;
        gap: var(--spacing-xs);
    }

    .btn-order-action {
        width: 100%;
    }

    /* Machine Grid */
    .machine-grid {
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: var(--spacing-sm);
    }

    /* Footer */
    .footer {
        margin: var(--spacing-sm);
        padding: var(--spacing-sm);
        font-size: var(--font-size-xs);
    }

    /* Edit Tabs */
    .edit-tabs .Wt-tabs li a,
    .edit-tabs .Wt-tabs li button {
        padding: 6px var(--spacing-sm);
        font-size: var(--font-size-sm);
    }

    /* Names Scroll Area */
    .names-scroll-area {
        max-height: 250px;
    }

    .names-scroll-area .lang-row {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--spacing-xs);
    }

    /* Import Dialog */
    .import-format-example {
        font-size: calc(10px * var(--font-scale));
        padding: var(--spacing-sm);
    }

    .file-upload {
        min-width: auto;
        width: 100%;
    }
}
.Wt-domRoot, body > div {
    height: 100% !important;
    overflow: hidden !important;
    margin: 0 !important;
    padding: 0 !important;
}

/* SpareParts page - full screen flex */
.spareparts-page {
    height: 100vh;
    width: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}

.spareparts-page .nav-container,
.spareparts-page .secondary-nav {
    flex: 0 0 auto;
}

.spareparts-page .content-container {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    padding: 0;
    margin: 0;
}

.spareparts-page .footer {
    flex: 0 0 auto;
    margin: 0;
    border-radius: 0;
}

/* Machine Page Layout */
.machine-page-layout {
    display: flex;
    width: 100%;
    height: 100%;
    min-height: 0;
    overflow: hidden;
    background: #f5f5f5;
}

/* Flex children: prevent overflow */
.panel-left,
.panel-center,
.panel-right,
.center-content-area,
.viewer-wrapper,
.bom-wrapper,
.part-info-sidebar,
.assembly-tree,
.assembly-tree-content,
.bom-viewer-container {
    min-height: 0;
}

/* Center panel flex layout */
.panel-center {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* Center content area — does not scroll; children scroll internally */
.center-content-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}

/* Viewer and BOM scroll containers */
.viewer-wrapper {
    flex: 1 1 50vh;
    min-height: 100px;
    overflow: auto;
}

.bom-wrapper {
    flex: 1 1 34vh;
    min-height: 0;
    overflow-y: auto;
}

/* Assembly tree scroll */
.assembly-tree {
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.assembly-tree-content {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;
}

/* Part info sidebar overflow */
.part-info-sidebar {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.part-info-content {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;
}
/* Import Button */
.btn-import {
    background-color: #17a2b8;
    color: white;
    border: none;
    padding: 8px 16px;
    border-radius: 4px;
    margin-left: 10px;
    cursor: pointer;
}

.btn-import:hover {
    background-color: #138496;
}

/* Import Dialog */

.import-path-section {
    background-color: #f8f9fa;
    padding: 15px;
    border-radius: 4px;
    margin-bottom: 10px;
}

.import-status {
    padding: 10px;
    border-radius: 4px;
    margin: 10px 0;
}

.import-status.status-info {
    background-color: #d1ecf1;
    color: #0c5460;
}

.import-status.status-error {
    background-color: #f8d7da;
    color: #721c24;
}

.import-status.status-success {
    background-color: #d4edda;
    color: #155724;
}

.import-results-container {
    border: 1px solid #dee2e6;
    border-radius: 4px;
    max-height: 350px;
}

.import-select-all {
    padding: 10px;
    background-color: #f8f9fa;
    border-bottom: 1px solid #dee2e6;
}

.import-results-table {
    width: 100%;
}

.import-results-table th,
.import-results-table td {
    padding: 8px 12px;
    border-bottom: 1px solid #dee2e6;
}

.import-results-table th {
    background-color: #e9ecef;
    font-weight: 600;
}

.import-new {
    color: #28a745;
    font-weight: 500;
}

.import-exists {
    color: #ffc107;
    font-weight: 500;
}

.import-progress {
    height: 20px;
    margin: 10px 0;
}
/* ============================================
   ADDITIONAL STYLES
   ============================================ */

/* Import Button */
.btn-import {
    background: #28a745;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-weight: 500;
}

.btn-import:hover {
    background: #218838;
}

/* Reset Button */
.btn-reset {
    background: #dc3545;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-weight: 500;
}

.btn-reset:hover {
    background: #c82333;
}

/* Auto Sort Button */
.btn-autosort {
    background: #6c757d;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-weight: 500;
}

.btn-autosort:hover {
    background: #5a6268;
}

/* btn-primary: uses var(--primary) green defined above */

/* btn-danger: uses var(--danger) defined above */

/* Import Table */
.import-table {
    width: 100%;
    border-collapse: collapse;
    margin: 15px 0;
}

.import-table th,
.import-table td {
    padding: 8px 12px;
    border: 1px solid #ddd;
    text-align: left;
}

.import-table th {
    background: #f5f5f5;
    font-weight: 600;
}

.import-table tr:nth-child(even) {
    background: #f9f9f9;
}

.import-table tr:hover {
    background: #e9ecef;
}

/* Status Text */
.status-text {
    padding: 10px 15px;
    border-radius: 4px;
    margin: 10px 0;
}

.status-success {
    background: #d4edda;
    color: #155724;
    border: 1px solid #c3e6cb;
}

.status-error {
    background: #f8d7da;
    color: #721c24;
    border: 1px solid #f5c6cb;
}

.status-warning {
    background: #fff3cd;
    color: #856404;
    border: 1px solid #ffeeba;
}
/* ADD these styles to your CSS file */

/* FileImportPanel styles */
.fileimport-table-container {
    border: 1px solid #ddd;
    border-radius: 4px;
    background: #fff;
}

.fileimport-table {
    width: 100%;
    border-collapse: collapse;
}

.fileimport-table th,
.fileimport-table td {
    padding: 8px 12px;
    text-align: left;
    border-bottom: 1px solid #eee;
}

.fileimport-table th {
    background: #f5f5f5;
    font-weight: 600;
    position: sticky;
    top: 0;
    z-index: 1;
}

.fileimport-table tr:hover {
    background: #f9f9f9;
}

.fileimport-row-existing {
    background: #fff3e0 !important;
}

.fileimport-row-existing:hover {
    background: #ffe0b2 !important;
}

.fileimport-status {
    padding: 8px 12px;
    border-radius: 4px;
    font-weight: 500;
}

.fileimport-status.status-success {
    background: #e8f5e9;
    color: #2e7d32;
}

.fileimport-status.status-error {
    background: #ffebee;
    color: #c62828;
}
/* Visibility wizard row styles */
.fileimport-row-bomchild {
    background-color: #e8f5e9 !important;
}

.fileimport-row-bomchild:hover {
    background-color: #c8e6c9 !important;
}

.fileimport-row-other {
    background-color: #fff8e1 !important;
}

.fileimport-row-other:hover {
    background-color: #ffecb3 !important;
}

.btn-small {
    padding: 2px 8px;
    font-size: calc(12px * var(--font-scale));
}
.fileimport-log {
    background: #263238;
    color: #eceff1;
    padding: 12px;
    border-radius: 4px;
    font-family: monospace;
    font-size: calc(12px * var(--font-scale));
    line-height: 1.6;
}

.fileimport-log .log-error {
    color: #ef5350;
}

.fileimport-log .log-success {
    color: #66bb6a;
}

.fileimport-log .log-phase {
    color: #42a5f5;
    font-weight: bold;
}
/* Assembly BOM Viewer Styles */

.assembly-bom-viewer-container {
    width: 100%;
    height: 100%;
    overflow: auto;
}

.assembly-bom-table-wrapper {
    padding: 10px;
}

.assembly-bom-table {
    width: 100%;
    border-collapse: collapse;
    font-size: calc(14px * var(--font-scale));
}

.assembly-bom-table th,
.assembly-bom-table td {
    padding: 10px 12px;
    border-bottom: 1px solid #e0e0e0;
    text-align: left;
}

.assembly-bom-table th {
    background: #f5f5f5;
    font-weight: 600;
    color: #333;
    position: sticky;
    top: 0;
    z-index: 1;
}

.assembly-bom-table tr:hover {
    background: #f8f9fa;
}

.assembly-bom-resolved {
    /* Resolved items - normal style */
}

.assembly-bom-unresolved {
    background: #fff8e1;
}

.assembly-bom-unresolved:hover {
    background: #ffecb3;
}

.bom-row-highlight {
    background: #e3f2fd !important;
}

.clickable-cell {
    cursor: pointer;
}

.clickable-cell:hover {
    color: #198754;
}

/* Assembly BOM: whole-row clickable combined cell */
.asm-bom-row-clickable {
    cursor: pointer;
}

.assembly-bom-table tr:has(.asm-bom-row-clickable):hover td {
    background: #f0f7f4;
}

/* Primary name text in combined assembly BOM cell */
.asm-bom-primary {
    display: block;
    font-weight: 500;
    color: #212529;
}

/* Secondary muted ETSL code below the name */
.asm-bom-secondary {
    display: block;
    font-size: 0.82em;
    color: #6c757d;
    margin-top: 2px;
}

.bom-cell-center {
    text-align: center;
}

.bom-empty-message {
    padding: 40px;
    text-align: center;
    color: #666;
    font-style: italic;
}

/* ===== Part Details Popup Styles ===== */

.popup-header-bar {
    background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
    color: white;
    border-bottom: 1px solid #1a252f;
}

.popup-header-bar h3 {
    color: white;
    font-weight: 500;
}

.popup-content-area {
    height: calc(100% - 60px);
    background: #f8f9fa;
}

.popup-left-panel {
    background: white;
    border-right: 1px solid #dee2e6;
    height: 100%;
}

.popup-right-panel {
    background: white;
    height: 100%;
}

/* SVG Container */
.svg-viewer-container {
    background: #ffffff;
    border: 1px solid #e9ecef;
    border-radius: 4px;
    min-height: 300px;
}

.svg-wrapper {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding: 10px;
}

.svg-wrapper svg {
    max-width: 100%;
    height: auto;
}

/* SVG clickable elements */
.svg-clickable {
    cursor: pointer;
    transition: all 0.15s ease;
}

.svg-clickable:hover {
    fill: #007bff !important;
    font-weight: bold;
}

/* BOM Table in popup */
.bom-table-compact {
    font-size: calc(13px * var(--font-scale));
}

.bom-table-compact th {
    padding: 8px 10px;
    background: #f1f3f4;
    font-weight: 600;
    font-size: calc(12px * var(--font-scale));
    text-transform: uppercase;
    letter-spacing: 0.3px;
}

.bom-table-compact td {
    padding: 6px 10px;
    border-bottom: 1px solid #e9ecef;
}

.bom-table-compact tr:hover {
    background: #f8f9fa;
}

.bom-table-compact .bom-row-selected {
    background: #cce5ff !important;
    border-left: 3px solid #007bff;
}

.bom-table-compact .bom-row-selected td {
    font-weight: 500;
}

/* Small cart button */
.btn-icon-cart-small {
    padding: 2px 6px;
    font-size: calc(12px * var(--font-scale));
    background: transparent;
    border: 1px solid #dee2e6;
    border-radius: 3px;
    cursor: pointer;
    transition: all 0.15s ease;
}

.btn-icon-cart-small:hover {
    background: #28a745;
    border-color: #28a745;
    transform: scale(1.1);
}

/* Muted text */
.muted {
    color: #6c757d;
    font-weight: normal;
}

/* Responsive */

@media (max-width: 768px) {
    .popup-content-area {
        flex-direction: column !important;
    }

    .popup-left-panel,
    .popup-right-panel {
        width: 100% !important;
        flex: none !important;
    }

    .popup-left-panel {
        height: 50%;
        border-right: none;
        border-bottom: 1px solid #dee2e6;
    }

    .popup-right-panel {
        height: 50%;
    }
}


/* ============================================
   RESPONSIVE - SMALL MOBILE (max-width: 360px)
   ============================================ */
@media only screen and (max-width: 360px) {
    :root {
        --font-size-base: calc(12px * var(--font-scale));
        --spacing-md: 8px;
        --spacing-lg: 10px;
    }

    .login-box {
        padding: var(--spacing-lg);
    }

    .login-logo {
        max-width: 100px;
    }

    .machine-dropdown,
    .search-input {
        min-width: 80px;
        font-size: calc(11px * var(--font-scale));
    }

    .nav-icon-btn {
        padding: var(--spacing-xs) var(--spacing-sm);
    }

    .assembly-bar-code {
        font-size: var(--font-size-sm);
    }
}

/* ============================================
   PRINT STYLES
   ============================================ */
@media print {
    .nav-container,
    .secondary-nav,
    .footer,
    .panel-left,
    .panel-resizer,
    .part-info-sidebar,
    .btn,
    .btn-icon,
    .assembly-bar-version,
    .svg-viewer-controls,
    .subasm-overlay {
        display: none !important;
    }

    .machine-page-layout,
    .panel-center,
    .center-content-area {
        height: auto !important;
        overflow: visible !important;
    }

    .bom-viewer-container {
        max-height: none !important;
        overflow: visible !important;
        box-shadow: none !important;
        border: 1px solid #ccc !important;
    }

    .bom-table {
        font-size: calc(11px * var(--font-scale));
    }

    .bom-table th {
        background: #f0f0f0 !important;
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    .assembly-bar {
        background: #f0f0f0 !important;
        color: #000 !important;
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
}

/* ============================================
   ADDITIONS: LAYOUT FIXES
   ============================================ */
.Wt-domRoot, body > div {
    height: 100% !important;
    overflow: hidden !important;
    margin: 0 !important;
    padding: 0 !important;
}

.spareparts-page {
    height: 100vh;
    width: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}

.spareparts-page .nav-container,
.spareparts-page .secondary-nav {
    flex: 0 0 auto;
}

.spareparts-page .content-container {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    padding: 0;
    margin: 0;
}

.spareparts-page .footer {
    flex: 0 0 auto;
    margin: 0;
    border-radius: 0;
}

.machine-page-layout {
    display: flex;
    width: 100%;
    height: 100%;
    min-height: 0;
    overflow: hidden;
    background: #f5f5f5;
}

.panel-left,
.panel-center,
.panel-right,
.center-content-area,
.viewer-wrapper,
.bom-wrapper,
.part-info-sidebar,
.assembly-tree,
.assembly-tree-content,
.bom-viewer-container {
    min-height: 0;
}

.panel-center {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* Center fixed — no page scroll; SVG and BOM scroll internally */
.center-content-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}

/* SVG viewer: fills alone; yields space to BOM when present */
.viewer-wrapper {
    flex: 1 1 50vh;
    min-height: 100px;
    overflow: auto;
}

/* BOM: internally scrolling box; scrollIntoView stays inside */
.bom-wrapper {
    flex: 1 1 34vh;
    min-height: 0;
    overflow-y: auto;
}

.assembly-tree {
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.assembly-tree-content {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;
}

.part-info-sidebar {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.part-info-content {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;
}

/* ============================================
   ADDITIONS: IMPORT STYLES
   ============================================ */
.btn-import {
    background: #28a745;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-weight: 500;
}
.btn-import:hover { background: #218838; }

.btn-reset {
    background: #dc3545;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
.btn-reset:hover { background: #c82333; }

.btn-autosort {
    background: #6c757d;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
.btn-autosort:hover { background: #5a6268; }

.import-table {
    width: 100%;
    border-collapse: collapse;
    margin: 15px 0;
}
.import-table th, .import-table td {
    padding: 8px 12px;
    border: 1px solid #ddd;
    text-align: left;
}
.import-table th { background: #f5f5f5; font-weight: 600; }
.import-table tr:nth-child(even) { background: #f9f9f9; }
.import-table tr:hover { background: #e9ecef; }

.fileimport-table-container {
    border: 1px solid #ddd;
    border-radius: 4px;
    background: #fff;
}
.fileimport-table { width: 100%; border-collapse: collapse; }
.fileimport-table th, .fileimport-table td {
    padding: 8px 12px;
    text-align: left;
    border-bottom: 1px solid #eee;
}
.fileimport-table th {
    background: #f5f5f5;
    font-weight: 600;
    position: sticky;
    top: 0;
    z-index: 1;
}
.fileimport-table tr:hover { background: #f9f9f9; }
.fileimport-row-existing { background: #fff3e0 !important; }
.fileimport-row-existing:hover { background: #ffe0b2 !important; }
.fileimport-status { padding: 8px 12px; border-radius: 4px; font-weight: 500; }
.fileimport-status.status-success { background: #e8f5e9; color: #2e7d32; }
.fileimport-status.status-error { background: #ffebee; color: #c62828; }

.fileimport-row-bomchild { background-color: #e8f5e9 !important; }
.fileimport-row-bomchild:hover { background-color: #c8e6c9 !important; }
.fileimport-row-other { background-color: #fff8e1 !important; }
.fileimport-row-other:hover { background-color: #ffecb3 !important; }

.fileimport-log {
    background: #263238;
    color: #eceff1;
    padding: 12px;
    border-radius: 4px;
    font-family: monospace;
    font-size: calc(12px * var(--font-scale));
    line-height: 1.6;
}
.fileimport-log .log-error { color: #ef5350; }
.fileimport-log .log-success { color: #66bb6a; }
.fileimport-log .log-phase { color: #42a5f5; font-weight: bold; }

/* ============================================
   ADDITIONS: ASSEMBLY BOM VIEWER
   ============================================ */
.assembly-bom-viewer-container { width: 100%; height: 100%; overflow: auto; }
.assembly-bom-table-wrapper { padding: 10px; }
.assembly-bom-table { width: 100%; border-collapse: collapse; font-size: calc(14px * var(--font-scale)); }
.assembly-bom-table th, .assembly-bom-table td {
    padding: 10px 12px; border-bottom: 1px solid #e0e0e0; text-align: left;
}
.assembly-bom-table th {
    background: #f5f5f5; font-weight: 600; color: #333;
    position: sticky; top: 0; z-index: 1;
}
.assembly-bom-table tr:hover { background: #f8f9fa; }
.assembly-bom-unresolved { background: #fff8e1; }
.assembly-bom-unresolved:hover { background: #ffecb3; }
.bom-row-highlight { background: #e3f2fd !important; }
.clickable-cell { cursor: pointer; }
.clickable-cell:hover { color: #198754; }

.popup-header-bar {
    background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
    color: white; border-bottom: 1px solid #1a252f;
}
.popup-header-bar h3 { color: white; font-weight: 500; }
.popup-content-area { height: calc(100% - 60px); background: #f8f9fa; }
.popup-left-panel { background: white; border-right: 1px solid #dee2e6; height: 100%; }
.popup-right-panel { background: white; height: 100%; }

.svg-viewer-container {
    background: #ffffff; border: 1px solid #e9ecef;
    border-radius: 4px; min-height: 300px;
}
.svg-wrapper { display: flex; justify-content: center; align-items: flex-start; padding: 10px; }
.svg-wrapper svg { max-width: 100%; height: auto; }
.svg-clickable { cursor: pointer; transition: all 0.15s ease; }
.svg-clickable:hover { fill: #007bff !important; font-weight: bold; }

.bom-table-compact { font-size: calc(13px * var(--font-scale)); }
.bom-table-compact th {
    padding: 8px 10px; background: #f1f3f4; font-weight: 600;
    font-size: calc(12px * var(--font-scale)); text-transform: uppercase; letter-spacing: 0.3px;
}
.bom-table-compact td { padding: 6px 10px; border-bottom: 1px solid #e9ecef; }
.bom-table-compact tr:hover { background: #f8f9fa; }
.bom-table-compact .bom-row-selected { background: #cce5ff !important; border-left: 3px solid #007bff; }
.bom-table-compact .bom-row-selected td { font-weight: 500; }

.btn-icon-cart-small {
    padding: 2px 6px; font-size: calc(12px * var(--font-scale)); background: transparent;
    border: 1px solid #dee2e6; border-radius: 3px; cursor: pointer;
}
.btn-icon-cart-small:hover { background: #28a745; border-color: #28a745; transform: scale(1.1); }
.muted { color: #6c757d; font-weight: normal; }

/* ThreeJS viewer panel styles */
.threejs-right-panel {
    height: 100%; display: flex; flex-direction: column;
    border-left: 1px solid rgba(0,0,0,0.08); background: rgba(255,255,255,0.85);
}
.threejs-parts-title { font-weight: 600; font-size: calc(14px * var(--font-scale)); padding: 6px 2px 2px 2px; }
.threejs-table-wrap {
    flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
    border: 1px solid rgba(0,0,0,0.10); border-radius: 10px; background: #fff;
}
.threejs-parts-table { width: 100%; border-collapse: collapse; }
.threejs-parts-table .thcell {
    position: sticky; top: 0; z-index: 2; background: #f6f7f9;
    border-bottom: 1px solid rgba(0,0,0,0.10); font-weight: 600; padding: 8px 10px;
}
.threejs-parts-table td { padding: 8px 10px; border-bottom: 1px solid rgba(0,0,0,0.06); vertical-align: middle; }
.threejs-parts-table tr:hover td { background: rgba(0,0,0,0.03); }
.threejs-parts-table td:nth-child(1) { width: 36px; }
.threejs-parts-table td:nth-child(3) { width: 80px; }
.threejs-parts-table td:nth-child(4) { width: 44px; }
.three-eye, .three-addcart {
    display: flex; align-items: center; justify-content: center; width: 32px; height: 28px; border-radius: 8px;
}
.clickable { cursor: pointer; }
.clickable:hover { background: rgba(0,0,0,0.06); }
.three-qty input { width: 60px; padding: 6px 8px; }
.three-name { display: block; font-size: calc(13px * var(--font-scale)); }
.bom-cart-header-wrap { display: flex; align-items: center; justify-content: center; gap: 6px; }

/* ============================================
   ADDITIONS: VERSION BADGE IN ASSEMBLY TREE
   ============================================ */
.assembly-tree-code-row {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.assembly-tree-version-badge {
    display: inline-block;
    font-size: calc(10px * var(--font-scale));
    font-weight: 600;
    background: var(--primary);
    color: var(--white);
    padding: 1px 6px;
    border-radius: 8px;
    white-space: nowrap;
    line-height: 1.4;
}

/* Spacing only: keeps the shared badge rule free of layout values. */
.search-asm-version {
    margin-left: 6px;
}

/* Draft chip shown next to the version badge for catalog editors: a draft
   primary node or a published node that hides a draft version. Amber to set
   it apart from the primary-coloured version badge. */
.assembly-tree-draft-badge {
    display: inline-block;
    font-size: calc(10px * var(--font-scale));
    font-weight: 600;
    background: #b45309;
    color: var(--white);
    padding: 1px 6px;
    border-radius: 8px;
    white-space: nowrap;
    line-height: 1.4;
    margin-left: 4px;
}

/* Shown on a dimmed (.assembly-tree-row-hidden) row: this sheet itself is
   not available for the currently selected machine number. Fainter than the
   version badge to match the row's reduced emphasis. */
.assembly-tree-hidden-badge {
    display: inline-block;
    font-size: calc(10px * var(--font-scale));
    font-weight: 600;
    background: var(--gray-300);
    color: var(--gray-700);
    padding: 1px 6px;
    border-radius: 8px;
    white-space: nowrap;
    line-height: 1.4;
    margin-left: 4px;
    max-width: 100%;
}

/* Create-version dialog */
.createver-headline {
    display: block;
    font-weight: 600;
    font-size: var(--font-size-md);
    margin-bottom: 4px;
}
.createver-contents-title {
    display: block;
    font-weight: 600;
    margin-top: 4px;
}
.createver-summary {
    margin: 2px 0 4px 0;
    padding-left: 2px;
    color: var(--gray-700);
    font-size: var(--font-size-sm);
}
.createver-draft-note {
    display: block;
    font-size: var(--font-size-sm);
    color: var(--gray-600);
    font-style: italic;
}
.createver-status {
    display: block;
    color: var(--danger, #b02a37);
    font-weight: 600;
}

/* ============================================
   ADDITIONS: CSV REVIEW TABLE
   ============================================ */
.csv-edit-input {
    padding: 2px 6px;
    font-size: var(--font-size-sm);
    border: 1px solid var(--gray-400);
    border-radius: var(--radius-sm);
}
.csv-flagged { border-color: #e74c3c; background: #fdf0ef; }
.csv-row-flagged { background: #fff5f4 !important; }
.csv-flag-warning { color: #e74c3c; font-size: var(--font-size-xs); font-weight: 500; }

/* ============================================
   ADDITIONS: CHILDREN TABLE (no-SVG fallback)
   ============================================ */
.children-table-wrapper {
    padding: 20px;
    height: 100%;
}

.children-table-heading {
    display: block;
    font-size: var(--font-size-xl);
    font-weight: 700;
    color: var(--gray-800);
    margin-bottom: 16px;
}

.children-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-base);
}

.children-table th {
    background: var(--gray-100);
    padding: 10px 14px;
    text-align: left;
    font-weight: 600;
    font-size: var(--font-size-sm);
    color: var(--gray-600);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border-bottom: 2px solid var(--gray-300);
}

.children-table td {
    padding: 12px 14px;
    border-bottom: 1px solid var(--gray-200);
    vertical-align: middle;
}

.children-table tr:hover td {
    background: var(--primary-light);
}

.children-table-cell-clickable {
    cursor: pointer;
}

/* Whole-row hover highlight so the child entry reads as one clickable unit. */
.children-table tr:hover td {
    background: #f0f7f4;
}

.children-table-name {
    font-weight: 500;
}

.viewer-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: var(--gray-500);
    font-size: var(--font-size-lg);
}

/* ============================================
   RESPONSIVE: FULL MOBILE OVERHAUL
   ============================================ */

/* Mobile hamburger button — hidden on desktop */
.mobile-menu-btn {
    display: none !important;
}

/* --- Tablet (max-width: 768px) --- */
@media only screen and (max-width: 768px) {
    /* Show hamburger */
    .mobile-menu-btn {
        display: inline-flex !important;
        background: rgba(255,255,255,0.2) !important;
        border: 1px solid rgba(255,255,255,0.4) !important;
        color: var(--white) !important;
        font-size: var(--font-size-xl) !important;
        padding: 4px 10px !important;
        border-radius: var(--radius-sm) !important;
        cursor: pointer !important;
        min-width: auto !important;
    }

    .mobile-menu-btn:hover {
        background: rgba(255,255,255,0.3) !important;
    }

    /* Layout stays row (not column!) */
    .machine-page-layout {
        flex-direction: row !important;
        height: 100vh !important;
        overflow: hidden !important;
        position: relative !important;
    }

    /* Left panel: hidden by default, slide-in overlay. Half the viewport
       width, full viewport height so the tree gets full vertical room
       while the page content stays partly visible on the right. */
    .machine-page-layout .panel-left {
        position: fixed !important;
        left: -45vw !important;
        top: 0 !important;
        bottom: 0 !important;
        width: 45vw !important;
        max-width: 45vw !important;
        min-width: 0 !important;
        height: 100vh !important;
        max-height: 100vh !important;
        /* Below Wt's dialog base of 1100: WDialog computes its z-index once,
           as max(1100, highest sibling popup + 1100), so a drawer above 1100
           hides the first dialog opened over it. Above .search-panel (1000). */
        z-index: 1050 !important;
        background: var(--white) !important;
        box-shadow: 4px 0 24px rgba(0,0,0,0.35) !important;
        transition: left 0.25s ease, transform 0.25s ease !important;
        overflow-y: auto !important;
        border-right: none !important;
        border-bottom: none !important;
        transform: translateX(0) !important;  /* override desktop collapsed transform */
    }

    /* Hidden state: slide off-screen using transform (also forces left
       just in case some other rule wins on `left`). */
    .machine-page-layout .panel-left,
    .machine-page-layout .panel-left.collapsed {
        left: -100% !important;
        transform: translateX(-100%) !important;
    }

    /* When open */
    .machine-page-layout .panel-left.mobile-open {
        left: 0 !important;
        transform: translateX(0) !important;
    }

    /* Backdrop dim behind the drawer so the user knows where to tap to
       close. Pseudo-element on the panel itself -- shown only when open. */
    .machine-page-layout .panel-left.mobile-open::before {
        content: '';
        position: fixed;
        inset: 0;
        background: rgba(0,0,0,0.45);
        z-index: -1;
    }

    /* The desktop "collapsed-to-icon-rail" rules (width:56px, opacity 1)
       must not show on phones -- force everything off-screen there. */
    .machine-page-layout .panel-left.collapsed .assembly-tree-header,
    .machine-page-layout .panel-left.collapsed .assembly-tree-content {
        display: block !important;
    }

    /* Here the sidebar is a drawer: off-screen whether or not it carries
       .collapsed, so its header cannot be the place the assembly name lives.
       Undo the desktop rule that hides the bar pill while the sidebar is
       "open", otherwise the name has nowhere to show on a phone. */
    .machine-page-layout .panel-left:not(.collapsed) ~ .panel-center .assembly-bar-name {
        display: inline-flex;
    }

    /* Center panel: full width always */
    .machine-page-layout .panel-center {
        width: 100% !important;
        min-width: 0 !important;
        flex: 1 1 auto !important;
        height: 100% !important;
        overflow: auto !important;
    }

    /* SVG viewer and BOM split the center column 50/50 instead of the
       vh-relative flex-basis (50vh/34vh), which ignores the assembly-bar's
       real height and drifts uneven on phones. Not !important: still loses
       to the drag-resize inline style and to the collapsed/expanded/
       full-list-mode toggle classes (all !important), only beats the plain
       .viewer-wrapper/.bom-wrapper base rule via the extra class. */
    .machine-page-layout .center-content-area {
        display: flex;
        flex-direction: column;
        min-height: 0;
    }

    .machine-page-layout .viewer-wrapper {
        flex: 1 1 50%;
        min-height: 0;
    }

    .machine-page-layout .bom-wrapper {
        flex: 1 1 50%;
        min-height: 0;
        overflow-y: auto;
    }

    /* Hide resizers */
    .vertical-resizer,
    #left-resizer,
    #right-resizer,
    .panel-resizer-right {
        display: none !important;
    }

    /* Assembly tree inside sidebar. 44px header + 40px search row. */
    .assembly-tree-content {
        max-height: calc(100vh - 44px - 40px);
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Assembly tree keeps the desktop look on every device per
       request: small inline arrow + compact row. Larger touch targets
       were dropped so phones see the same tidy list as Mac. */

    .assembly-tree-version-badge { font-size: calc(11px * var(--font-scale)); padding: 2px 6px; }
    .assembly-tree-hidden-badge { font-size: calc(11px * var(--font-scale)); padding: 2px 6px; }

    /* Assembly bar -- keep text readable, touch targets >= 44px */
    .assembly-bar-top {
        flex-wrap: nowrap !important;
        padding: 8px 12px !important;
        gap: 8px !important;
    }
    .assembly-bar-name {
        font-size: var(--font-size-base) !important;
        max-width: 100% !important;
    }
    .assembly-bar-control { font-size: var(--font-size-base); }
    .assembly-bar-dropdown {
        font-size: var(--font-size-base) !important;
        padding: 0 24px 0 10px !important;
        height: 32px !important;
        min-height: 32px !important;
    }

    /* Children / BOM table -- larger text + touch-friendly rows. */
    .children-table-wrapper { padding: 12px; }
    .children-table-heading { font-size: var(--font-size-xl); margin-bottom: 12px; }
    .children-table th, .children-table td {
        padding: 12px 10px;
        font-size: var(--font-size-base);
    }
    .children-table th:first-child, .children-table td:first-child { display: none; }

    /* Import dialog */
    .fileimport-log { font-size: var(--font-size-sm); }

    /* Part details popup */
    .popup-content-area { flex-direction: column !important; }
    .popup-left-panel, .popup-right-panel { width: 100% !important; flex: none !important; }
    .popup-left-panel { height: 50%; border-right: none; border-bottom: 1px solid #dee2e6; }
    .popup-right-panel { height: 50%; }

    /* Part info sidebar: slide-in drawer from the right, 60% of the
       viewport, mirroring the .panel-left drawer above. The slide animates
       `right` rather than `transform`: a transform would make the panel the
       containing block for its fixed-position ::before backdrop, and
       overflow:hidden would then clip the backdrop away. */
    .part-info-sidebar {
        position: fixed !important;
        right: 0 !important;
        top: 0 !important;
        bottom: 0 !important;
        width: 60vw !important;
        max-width: 60vw !important;
        min-width: 0 !important;
        height: 100vh !important;
        max-height: 100vh !important;
        /* Below Wt's dialog base of 1100: WDialog computes its z-index once,
           as max(1100, highest sibling popup + 1100), so a drawer above 1100
           hides the first dialog opened over it. Above .search-panel (1000). */
        z-index: 1050 !important;
        background: var(--white) !important;
        box-shadow: -4px 0 24px rgba(0,0,0,0.35) !important;
        transform: none !important;
        transition: right 0.25s ease !important;
    }

    /* Hidden state: slide off-screen instead of display:none so the
       transition runs; width is kept so the panel does not reflow. */
    .part-info-sidebar.collapsed {
        width: 60vw !important;
        right: -100% !important;
        pointer-events: none !important;
        box-shadow: none !important;
    }

    /* Backdrop dim behind the drawer. Pseudo-element on the panel itself,
       shown only when open. */
    .part-info-sidebar:not(.collapsed)::before {
        content: '';
        position: fixed;
        inset: 0;
        background: rgba(0,0,0,0.45);
        z-index: -1;
    }

    /* Homepage machine grid */
    .machine-grid { gap: var(--spacing-md); }
    .machine-card { max-width: 100%; }

    /* Cart */
    .cart-toolbar { flex-wrap: wrap; }
    .cart-selector-dropdown-small { width: 100%; }

    /* Dialogs full-screen on mobile so content has room and the footer
       buttons can't disappear below the fold. C++ side often calls
       resize(720,520) which inline-pins width/height; we override here
       with !important and switch to a flex column so the body scrolls
       while the titlebar and footer stay pinned. transform:none clears
       Wt's centering translate so left/top:0 actually win. Selector
       includes `body div` for extra specificity. */
    body div.Wt-dialog,
    .Wt-dialog {
        position: fixed !important;
        top: 0 !important;
        left: 0 !important;
        right: 0 !important;
        bottom: 0 !important;
        width: 100vw !important;
        min-width: 100vw !important;
        max-width: 100vw !important;
        height: 100vh !important;
        min-height: 100vh !important;
        max-height: 100vh !important;
        margin: 0 !important;
        padding: 0 !important;
        border-radius: 0 !important;
        transform: none !important;
        display: flex !important;
        flex-direction: column !important;
    }

    /* Wt 4 wraps the dialog contents in a .Wt-dialog-contents div. Make
       that wrapper transparent to the flex layout (display:contents)
       so the titlebar/body/footer become direct flex children of
       .Wt-dialog. Without this, body and footer cluster inside the
       wrapper and the footer floats wherever the wrapper happens to
       sit, leaving big empty white below. */
    .Wt-dialog > .Wt-dialog-contents,
    .Wt-dialog > .contents {
        display: contents !important;
    }

    .Wt-dialog .titlebar,
    .Wt-dialog .Wt-dialog-title-bar {
        flex: 0 0 auto !important;
        padding: var(--spacing-md) var(--spacing-lg) !important;
    }

    .Wt-dialog .body,
    .Wt-dialog .Wt-dialog-body {
        flex: 1 1 auto !important;
        overflow-y: auto !important;
        overflow-x: hidden !important;
        padding: var(--spacing-md) !important;
        min-height: 0 !important;
    }

    .Wt-dialog .Wt-dialog-footer {
        flex: 0 0 auto !important;
        padding: var(--spacing-md) var(--spacing-lg) !important;
        display: flex !important;
        flex-wrap: wrap !important;
        gap: var(--spacing-sm) !important;
    }

    /* Footer buttons stretch and wrap so each remains tappable even on
       narrow screens. Targets generic dialog buttons + the per-dialog
       pdf-btn family used by PdfExportDialog. */
    .Wt-dialog .Wt-dialog-footer button,
    .Wt-dialog .Wt-dialog-footer .pdf-btn,
    .Wt-dialog .Wt-msgbox-buttons button {
        flex: 1 1 auto !important;
        min-width: 80px !important;
        margin-right: 0 !important;
    }

    /* The zoom dial stays on touch: it opens on tap instead of hover, and
       pinch-zoom keeps working alongside it. Targets grow for finger use. */
    .svg-viewer-controls.svg-zoom-dial {
        width: 116px;
        height: 116px;
    }

    .svg-zoom-dial .szd-center {
        width: 38px;
        height: 38px;
        margin: -19px 0 0 -19px;
    }

    .svg-zoom-dial .szd-sat {
        width: 36px;
        height: 36px;
        margin: -18px 0 0 -18px;
    }

    .svg-zoom-dial.is-open .szd-up    { transform: translate(0, -42px); }
    .svg-zoom-dial.is-open .szd-down  { transform: translate(0, 42px); }
    .svg-zoom-dial.is-open .szd-left  { transform: translate(-42px, 0); }
    .svg-zoom-dial.is-open .szd-right { transform: translate(42px, 0); }
    .svg-zoom-dial.is-open .szd-downleft { transform: translate(-42px, 42px); }

    .subasm-overlay {
        max-width: 70vw;
    }

    /* The part-info drawer slides over the viewer on small screens; the dial
       and the overlay must not float above it. */
    body:has(.part-info-sidebar:not(.collapsed)) .machine-page-layout .svg-viewer-controls,
    body:has(.part-info-sidebar:not(.collapsed)) .machine-page-layout .subasm-overlay {
        display: none !important;
    }
}

/* --- Small mobile (max-width: 480px) --- */
@media only screen and (max-width: 480px) {
    .machine-page-layout .panel-left.mobile-open { left: 0 !important; }

    .panel-left { width: 80vw !important; max-width: 80vw !important; }

    .part-info-sidebar,
    .part-info-sidebar.collapsed { width: 80vw !important; max-width: 80vw !important; }

    .assembly-tree-code-row { flex-direction: column; align-items: flex-start; gap: 2px; }
    .assembly-tree-name { font-size: calc(10px * var(--font-scale)) !important; }
    .assembly-tree-code { font-size: calc(9.5px * var(--font-scale)) !important; }
    /* Longer badge text (e.g. "for other machines") wraps instead of
       pushing the row wider than the viewport. */
    .assembly-tree-hidden-badge { white-space: normal; }

    .children-table th, .children-table td {
        padding: 10px 8px;
        font-size: var(--font-size-base);
    }
    .machine-grid { justify-content: center; }
    .machine-card { width: 100%; max-width: 100%; }
    .cart-items-table th, .cart-items-table td {
        padding: 8px;
        font-size: var(--font-size-sm);
    }
    .cart-part-thumbnail { max-width: 40px; max-height: 30px; }
}

/* --- Very small mobile (max-width: 360px) --- */
@media only screen and (max-width: 360px) {
    .login-box { padding: var(--spacing-lg); }
    .login-logo { max-width: 100px; }
    .assembly-bar-code { font-size: var(--font-size-base); }
}

/* Compact machine header on phones: keep the working area visible first. */
@media only screen and (max-width: 768px) {
    .nav-container {
        display: grid !important;
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: center;
        gap: 4px 6px !important;
        padding: 4px 10px !important;
    }

    .nav-logo-link {
        min-width: 0;
    }

    .nav-container .Wt-image,
    .nav-container img,
    .nav-logo-img {
        width: auto !important;
        max-width: min(170px, 50vw) !important;
        height: auto !important;
        max-height: 24px !important;
    }

    .user-dropdown-btn {
        justify-self: end;
        order: initial;
        height: 24px !important;
        max-width: 150px;
        margin-left: 0 !important;
        padding: 0 7px !important;
        border-radius: 5px;
    }

    .user-dropdown-name {
        max-width: 118px;
        font-size: 11px;
    }

    .nav-right-host {
        grid-column: 1 / -1;
        order: initial;
        flex-basis: auto;
        width: 100%;
        margin-left: 0;
        justify-content: flex-start;
        gap: 5px !important;
    }

    .nav-right-host .machine-dropdown,
    .nav-right-host .company-switch,
    .action-bar .machine-dropdown,
    .action-bar .company-switch {
        height: 30px !important;
        max-width: 160px;
        min-width: 0;
        flex: 0 1 auto;
        padding: 3px 24px 3px 8px !important;
        font-size: calc(11px * var(--font-scale)) !important;
    }

    .nav-right-host .nav-icon-btn,
    .action-bar .nav-icon-btn {
        width: 30px !important;
        height: 30px !important;
        min-width: 30px !important;
        margin-left: 0 !important;
    }

    .nav-right-host .nav-icon-btn img,
    .action-bar .nav-icon-btn img {
        width: 16px !important;
        height: 16px !important;
    }

    .action-bar {
        min-height: 34px;
        padding: 3px 10px !important;
        gap: 5px !important;
        row-gap: 3px;
    }

    .action-bar-spacer {
        display: none;
    }

    .assembly-bar {
        min-height: 32px;
    }

    .assembly-bar-top {
        min-height: 32px !important;
        padding: 3px 10px !important;
        gap: 5px !important;
        row-gap: 3px !important;
    }

    .assembly-bar-left {
        flex: 1 1 auto;
        flex-direction: row !important;
        align-items: center !important;
        gap: 5px !important;
        min-width: 0;
    }

    .mobile-menu-btn {
        width: 28px !important;
        height: 28px !important;
        min-width: 28px !important;
        padding: 0 !important;
    }

    .assembly-bar-pill {
        min-height: 28px;
        padding: 3px 8px !important;
        font-size: calc(11px * var(--font-scale)) !important;
        line-height: 20px;
    }

    .assembly-bar-name {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: calc(11px * var(--font-scale)) !important;
    }

    .assembly-bar-code {
        font-size: calc(12px * var(--font-scale)) !important;
        letter-spacing: 0;
    }

    .assembly-bar-version,
    .assembly-bar-control {
        width: auto !important;
        flex: 0 1 auto;
        gap: 4px;
        font-size: calc(11px * var(--font-scale)) !important;
    }

    .assembly-bar-version label,
    .assembly-bar-control label {
        display: none;
    }

    .assembly-bar-dropdown,
    .assembly-bar-version select {
        min-height: 28px !important;
        height: 28px !important;
        min-width: 54px;
        padding: 3px 24px 3px 7px !important;
        font-size: calc(11px * var(--font-scale)) !important;
    }
}

@media only screen and (max-width: 480px) {
    .nav-container .Wt-image,
    .nav-container img,
    .nav-logo-img {
        max-width: min(158px, 48vw) !important;
        max-height: 22px !important;
    }

    .user-dropdown-btn {
        max-width: 138px;
    }

    .user-dropdown-name {
        max-width: 104px;
    }

    .assembly-bar-name {
        max-width: 31vw !important;
    }

    .assembly-bar-version label,
    .assembly-bar-control label {
        display: none;
    }
}

/* ============================================
   IMPORT DIALOG: GROUPED PREVIEW
   ============================================ */
.import-group {
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-md);
    margin-bottom: 6px;
    background: var(--white);
}

.import-group-header {
    padding: 8px 12px;
    background: var(--gray-100);
    border-bottom: 1px solid var(--gray-200);
    font-size: var(--font-size-sm);
    cursor: default;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
}

.import-group-children {
    padding: 4px 0;
}

.import-group-child-row {
    padding: 4px 12px;
    font-size: var(--font-size-sm);
    font-family: var(--font-mono);
    color: var(--gray-700);
    border-bottom: 1px solid var(--gray-100);
}

.import-group-child-row:last-child {
    border-bottom: none;
}

.import-group-child-row:hover {
    background: var(--primary-light);
}

.import-flagged-section {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 2px solid #e74c3c;
}

.import-target-group {
    font-family: var(--font-mono);
    font-size: var(--font-size-sm);
    color: var(--primary);
    font-weight: 600;
}

@media only screen and (max-width: 768px) {
    .import-group-header { padding: 6px 8px; font-size: var(--font-size-xs); }
    .import-group-child-row { padding: 3px 8px; font-size: var(--font-size-xs); }
}

/* ============================================
   IMPORT: INLINE NAME EDITING
   ============================================ */
.import-inline-name-edit {
    padding: 3px 8px;
    font-size: var(--font-size-sm);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
    background: var(--white);
    min-width: 120px;
}

.import-inline-name-edit:focus {
    border-color: var(--primary);
    outline: none;
    box-shadow: 0 0 0 2px rgba(25, 135, 84, 0.15);
}

.import-inline-name-edit-sm {
    padding: 2px 6px;
    font-size: var(--font-size-xs);
}

.import-group-count {
    font-size: var(--font-size-xs);
    color: var(--gray-500);
    white-space: nowrap;
}

.import-child-code {
    font-family: var(--font-mono);
    font-size: var(--font-size-xs);
    white-space: nowrap;
    min-width: 200px;
}

@media only screen and (max-width: 768px) {
    .import-inline-name-edit { min-width: 80px; font-size: var(--font-size-xs); }
    .import-child-code { min-width: 140px; font-size: calc(10px * var(--font-scale)); }
    .import-group-header { padding: 4px 6px; }
}

/* ============================================
   IMPORT: TREE TABLE
   ============================================ */
.import-tree-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
}

.import-tree-table th {
    background: var(--gray-100);
    padding: 6px 10px;
    text-align: left;
    font-weight: 600;
    font-size: var(--font-size-xs);
    color: var(--gray-600);
    text-transform: uppercase;
    border-bottom: 2px solid var(--gray-300);
}

.import-tree-table td {
    padding: 5px 10px;
    border-bottom: 1px solid var(--gray-100);
    vertical-align: middle;
}

.import-tree-group-row {
    background: var(--gray-100) !important;
    border-bottom: 1px solid var(--gray-300) !important;
}

.import-tree-group-cell {
    font-weight: 600;
}

.import-tree-child-code {
    font-family: var(--font-mono);
    font-size: var(--font-size-xs);
    color: var(--gray-600);
}

.import-tree-table tr:hover td {
    background: var(--primary-light);
}

/* ============================================
   Bilingual names import preview
   ============================================ */
.settings-import-table {
    border-collapse: collapse;
    width: auto;
}

.settings-import-table th,
.settings-import-table td {
    padding: 6px 10px;
    border: 1px solid var(--gray-300);
    vertical-align: top;
    font-size: 0.9rem;
    white-space: nowrap;
}

.settings-import-table td,
.settings-import-table th {
    min-width: 90px;
}

.settings-import-table th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--gray-100);
    font-weight: 600;
}

.settings-import-table .import-col-code {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--white);
    font-family: var(--font-mono);
}

.settings-import-table th.import-col-code {
    z-index: 3;
    background: var(--gray-100);
}

.import-cell-current {
    color: var(--gray-500);
    font-size: 0.85em;
}

.import-cell-changed {
    background: #fff3cd;
    font-weight: 600;
}

.badge-update {
    display: inline-block;
    padding: 2px 8px;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    color: var(--white);
    background: var(--info);
}

.badge-new {
    display: inline-block;
    padding: 2px 8px;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    color: var(--white);
    background: var(--success);
}

.badge-skip {
    display: inline-block;
    padding: 2px 8px;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    color: var(--white);
    background: var(--gray-500);
}

.badge-neutral {
    display: inline-block;
    padding: 2px 8px;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    color: var(--gray-700);
    background: var(--gray-100);
}

/* ============================================
   EDIT MODE: INLINE ASSEMBLY BAR EDITING
   ============================================ */
.assembly-bar-edit-btn {
    background: rgba(255,255,255,0.2) !important;
    border: 1px solid rgba(255,255,255,0.4) !important;
    color: var(--white) !important;
    padding: 4px 12px !important;
    border-radius: var(--radius-sm) !important;
    font-size: var(--font-size-sm) !important;
    cursor: pointer !important;
    white-space: nowrap;
    min-width: auto !important;
}

.assembly-bar-edit-btn:hover {
    background: rgba(255,255,255,0.3) !important;
}

.assembly-bar-edit-btn.active {
    background: #e74c3c !important;
    border-color: #c0392b !important;
}

.assembly-bar-name-edit {
    background: rgba(255,255,255,0.9);
    border: 2px solid rgba(255,255,255,0.6);
    border-radius: var(--radius-sm);
    padding: 4px 10px;
    font-size: var(--font-size-base);
    font-weight: 600;
    color: var(--gray-800);
    min-width: 180px;
    max-width: 300px;
}

.assembly-bar-name-edit:focus {
    border-color: var(--white);
    outline: none;
    box-shadow: 0 0 0 2px rgba(255,255,255,0.3);
}

.assembly-bar-note-edit {
    background: rgba(255,255,255,0.15);
    border: 1px solid rgba(255,255,255,0.4);
    border-radius: var(--radius-sm);
    padding: 4px 10px;
    font-size: var(--font-size-sm);
    color: var(--white);
    min-width: 120px;
    max-width: 250px;
}

.assembly-bar-note-edit:focus {
    background: rgba(255,255,255,0.25);
    border-color: var(--white);
    outline: none;
}

.assembly-bar-note-edit::placeholder {
    color: rgba(255,255,255,0.5);
}

@media only screen and (max-width: 768px) {
    .assembly-bar-name-edit { min-width: 120px; max-width: 100%; font-size: var(--font-size-sm); }
    .assembly-bar-note-edit { min-width: 80px; max-width: 100%; }
    .assembly-bar-edit-btn { padding: 3px 8px !important; font-size: var(--font-size-xs) !important; }
}

/* ============================================
   EDIT ASSEMBLY: SEARCH BAR + INLINE EDIT
   ============================================ */
.edit-search-bar {
    background: var(--white);
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-md);
    padding: 6px 10px;
    width: 100%;
    min-height: 48px;
    box-sizing: border-box;
    overflow: hidden;
    display: flex !important;
    align-items: center;
    gap: 8px;
}

.edit-search-bar .edit-search-icon {
    width: 16px !important;
    height: 16px !important;
    min-width: 16px !important;
    max-width: 16px !important;
    flex: 0 0 16px !important;
    display: block;
    opacity: 0.65;
}

.edit-search-bar .edit-search-clear {
    width: 32px;
    height: 32px;
    min-width: 32px;
    padding: 0 !important;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.edit-search-bar .edit-search-clear .app-icon {
    width: 14px !important;
    height: 14px !important;
    flex-basis: 14px;
}

.edit-search-bar .edit-search-input {
    height: 34px !important;
    flex: 1 1 auto;
    min-width: 0;
    padding: 0 6px !important;
    border: 0 !important;
    border-radius: 0;
    font-size: var(--font-size-base);
    line-height: 34px !important;
    background: transparent;
    width: 100%;
    box-sizing: border-box;
    margin: 0 !important;
}

.edit-search-bar .edit-search-input:focus {
    border-color: transparent;
    outline: none;
    box-shadow: none;
}

.edit-assembly-title {
    font-size: var(--font-size-lg);
    color: var(--gray-800);
    white-space: nowrap;
}

.edit-assembly-count {
    font-size: var(--font-size-sm);
    color: var(--gray-500);
    white-space: nowrap;
    margin-left: auto;
}

.edit-inline-clickable {
    cursor: pointer;
    padding: 2px 6px;
    border-radius: var(--radius-sm);
    transition: background var(--transition-fast);
}

.edit-inline-clickable:hover {
    background: var(--primary-light);
}

.edit-inline-input {
    padding: 4px 8px;
    border: 2px solid var(--primary);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-base);
    width: 100%;
    background: #fffbe6;
}

.edit-inline-input:focus {
    outline: none;
    box-shadow: 0 0 0 2px rgba(25, 135, 84, 0.2);
}

@media only screen and (max-width: 768px) {
    .edit-search-bar { padding: 6px 8px; }
    .edit-search-input { font-size: var(--font-size-sm); }
    .edit-assembly-title { font-size: var(--font-size-base); }
    .edit-inline-input { font-size: var(--font-size-sm); }
}

/* ============================================
   EDIT ASSEMBLY: FOLDER NAVIGATION
   ============================================ */
.edit-breadcrumb {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px;
    padding: 6px 12px;
    background: var(--gray-100);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    min-height: 32px;
}

.edit-breadcrumb:empty {
    display: none;
}

.edit-breadcrumb-link {
    background: none !important;
    border: none !important;
    color: var(--primary) !important;
    padding: 2px 4px !important;
    font-size: var(--font-size-sm) !important;
    cursor: pointer !important;
    text-decoration: underline !important;
    min-width: auto !important;
}

.edit-breadcrumb-link:hover {
    color: var(--primary-dark) !important;
}

.edit-breadcrumb-current {
    color: var(--gray-800);
    font-size: var(--font-size-sm);
}

.edit-folder-link {
    color: var(--primary);
    cursor: pointer;
    font-weight: 600;
}

.edit-folder-link:hover {
    color: var(--primary-dark);
    text-decoration: underline;
}

.edit-icon-cell {
    width: 30px;
    text-align: center;
    font-size: var(--font-size-lg);
}

@media only screen and (max-width: 768px) {
    .edit-breadcrumb { padding: 4px 8px; font-size: var(--font-size-xs); }
    .edit-icon-cell { width: 24px; font-size: var(--font-size-base); }
}

/* ============================================
   FIX: NAMES TAB IN EDIT ASSEMBLY DIALOG
   ============================================ */
.names-scroll-area {
    max-height: 450px;
    overflow-y: auto;
    border: 1px solid #e5e7eb;
    border-radius: var(--radius-lg);
    background-color: var(--white);
    padding: var(--spacing-md) var(--spacing-lg);
}

.names-scroll-area .Wt-hboxlayout {
    align-items: center !important;
}

.names-scroll-area .Wt-hboxlayout > div:first-child {
    min-width: 110px !important;
    max-width: 110px !important;
    font-size: var(--font-size-sm);
    font-weight: 500;
    color: var(--gray-700);
}

.names-scroll-area .edit-input {
    width: 100% !important;
    min-width: 0 !important;
}

.names-scroll-area .btn-icon-translate {
    font-size: var(--font-size-lg) !important;
    min-width: 36px !important;
    width: 36px !important;
    height: 36px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    background: var(--primary-light) !important;
    border-radius: var(--radius-sm) !important;
    flex-shrink: 0;
}

.names-scroll-area .btn-icon-translate:hover {
    background: var(--primary) !important;
    color: var(--white) !important;
}

/* ============================================
   VISIBILITY: RANGE SELECTION BAR
   ============================================ */
.visibility-range-bar {
    background: var(--gray-100);
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-md);
    box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}

.vis-range-combo {
    padding: 0 10px;
    height: 34px;
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    min-width: 150px;
    background: #fff;
}

.vis-range-input {
    padding: 0 10px;
    height: 34px;
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    text-align: center;
    background: #fff;
}

.vis-range-input:focus,
.vis-range-combo:focus {
    border-color: var(--primary);
    outline: none;
    box-shadow: 0 0 0 2px rgba(25, 135, 84, .12);
}

.vis-count-text {
    font-size: var(--font-size-sm);
    color: var(--gray-600);
}

@media only screen and (max-width: 768px) {
    .visibility-range-bar .Wt-hboxlayout { flex-wrap: wrap !important; }
    .vis-range-combo { min-width: 100px; font-size: var(--font-size-xs); }
    .vis-range-input { width: 50px !important; }
}

/* ============================================
   FIX: NAMES TAB — FORCE LAYOUT
   ============================================ */
.names-scroll-area > div > div > div {
    display: flex !important;
    align-items: center !important;
    gap: 10px !important;
    margin-bottom: 6px !important;
    min-height: 36px !important;
}

.names-scroll-area > div > div > div > div:first-child {
    min-width: 120px !important;
    max-width: 120px !important;
    flex-shrink: 0 !important;
    font-size: calc(13px * var(--font-scale)) !important;
    font-weight: 500 !important;
    color: var(--gray-700) !important;
}

.names-scroll-area > div > div > div > div:nth-child(2) {
    flex: 1 !important;
    min-width: 0 !important;
}

.names-scroll-area > div > div > div > div:nth-child(2) input,
.names-scroll-area .edit-input {
    width: 100% !important;
    padding: 6px 10px !important;
    font-size: calc(13px * var(--font-scale)) !important;
}

.names-scroll-area > div > div > div > div:nth-child(3) {
    flex-shrink: 0 !important;
}

.names-scroll-area .btn-icon-translate {
    width: 34px !important;
    height: 34px !important;
    min-width: 34px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    background: var(--primary-light) !important;
    border: 1px solid var(--primary) !important;
    border-radius: var(--radius-sm) !important;
    font-size: calc(16px * var(--font-scale)) !important;
    cursor: pointer !important;
    padding: 0 !important;
}

.names-scroll-area .btn-icon-translate:hover {
    background: var(--primary) !important;
    color: var(--white) !important;
}

/* ============================================
   NAMES TAB: TABLE-BASED LAYOUT
   ============================================ */
.names-edit-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}

.names-edit-table td {
    padding: 6px 8px;
    vertical-align: middle;
    border-bottom: 1px solid var(--gray-200);
    overflow: hidden;
}

.names-edit-table td:first-child {
    width: 130px !important;
    font-size: calc(13px * var(--font-scale));
    font-weight: 600;
    color: var(--gray-700);
    white-space: nowrap;
}

.names-edit-table td:nth-child(2) {
    width: auto;
}

.names-edit-table td:nth-child(2) input {
    width: 100% !important;
    box-sizing: border-box;
    padding: 6px 10px;
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
    font-size: calc(13px * var(--font-scale));
}

.names-edit-table td:nth-child(2) input:focus {
    border-color: var(--primary);
    outline: none;
}

.names-edit-table td:last-child {
    width: 44px !important;
    text-align: center;
}

.btn-translate {
    width: 34px !important;
    height: 34px !important;
    min-width: 34px !important;
    padding: 0 !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    background: var(--primary-light) !important;
    border: 1px solid var(--primary) !important;
    border-radius: var(--radius-sm) !important;
    font-size: calc(16px * var(--font-scale)) !important;
    cursor: pointer !important;
}

.btn-translate:hover {
    background: var(--primary) !important;
    color: var(--white) !important;
}
/* ================================================================
   SHOPPING CART: PAGE-LEVEL
   ================================================================ */

.shopping-cart-page {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}

.shopping-cart-page > div {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
    overflow: hidden;
}

.shopping-cart-page > .Wt-stack,
.shopping-cart-page > .Wt-stack > div {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
    overflow: hidden;
}

.cart-top-bar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    align-items: center;
    padding: var(--spacing-sm) var(--spacing-md);
    background: var(--white);
    flex-shrink: 0;
    border-bottom: 1px solid var(--gray-200);
}

.cart-top-bar > * {
    flex: 0 0 auto;
}
.cart-top-spacer {
    flex: 1 1 auto;
    min-width: var(--spacing-md);
}
.cart-top-right-actions {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    flex: 0 0 auto;
}
.cart-top-action-btn {
    min-width: 104px !important;
    height: 34px !important;
    margin: 0 !important;
    padding: 0 14px !important;
    border-radius: var(--radius-sm) !important;
    font-size: var(--font-size-sm) !important;
    line-height: 32px !important;
    box-sizing: border-box;
    white-space: nowrap;
}
.cart-actions-menu-btn {
    display: none !important;
}
.cart-actions-popup-menu .item .Wt-icon {
    width: 16px;
    height: 16px;
}
.cart-mobile-show-more-btn {
    display: none !important;
}
.cart-favorites-icon-btn {
    width: 34px !important;
    min-width: 34px !important;
    padding: 0 !important;
    border: 1px solid var(--primary-dark) !important;
    background: var(--primary-dark) !important;
    color: var(--white) !important;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
}
.cart-favorites-icon-btn::before {
    content: "";
    display: block;
    width: 18px;
    height: 18px;
    background: var(--white);
    -webkit-mask: url('../files/essentials/star.svg') center / contain no-repeat;
    mask: url('../files/essentials/star.svg') center / contain no-repeat;
}
.cart-favorites-icon-btn:hover {
    background: var(--primary) !important;
    border-color: var(--primary) !important;
}

/* Cart "Quick add" toolbar button and popup. */
.cart-quick-add-btn img,
.cart-quick-add-search-btn img {
    width: 16px !important;
    height: 16px !important;
    margin-right: 6px;
    vertical-align: middle;
}
.cart-quick-add-dialog > .dialog-layout,
.cart-quick-add-dialog .body {
    width: 100% !important;
    box-sizing: border-box !important;
}
.cart-quick-add-dialog .body {
    padding: 16px 20px;
}
.cart-quick-add-search {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
}
.cart-quick-add-input {
    flex: 1 1 auto;
    min-width: 0;
    height: 36px;
    box-sizing: border-box;
}
.cart-quick-add-status {
    display: block;
    margin-top: 10px;
    font-size: var(--font-size-sm);
    color: var(--gray-700);
}
.cart-quick-add-status.is-error {
    color: #b02a37;
}
.cart-quick-add-status.is-ok {
    color: #198754;
    font-weight: 600;
}
.cart-quick-add-results {
    margin-top: 8px;
    max-height: 260px;
    overflow-y: auto;
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
}
.cart-quick-add-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 10px;
    border-bottom: 1px solid var(--gray-200);
    cursor: pointer;
}
.cart-quick-add-row:last-child {
    border-bottom: 0;
}
.cart-quick-add-row:hover {
    background: var(--gray-100);
}
.cart-quick-add-row.is-selected {
    background: #e7f1ff;
}
.cart-quick-add-thumb {
    width: 40px;
    height: 40px;
    flex: 0 0 40px;
    object-fit: contain;
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: 4px;
    box-sizing: border-box;
}
.cart-quick-add-row-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.cart-quick-add-row-title {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--gray-800);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cart-quick-add-row-machine {
    font-size: var(--font-size-xs);
    color: var(--gray-600);
}
.cart-quick-add-detail {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--gray-200);
}
.cart-quick-add-detail-top {
    display: flex;
    align-items: flex-start;
    gap: 16px;
}
.cart-quick-add-img {
    width: 110px;
    height: 110px;
    flex: 0 0 110px;
    object-fit: contain;
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: 6px;
    padding: 4px;
    box-sizing: border-box;
}
.cart-quick-add-noimg {
    display: flex;
    align-items: center;
    justify-content: center;
}
.cart-quick-add-noimg img {
    width: 24px !important;
    height: 24px !important;
    opacity: 0.35;
}
.cart-quick-add-info {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    gap: 4px;
}
.cart-quick-add-name {
    font-weight: 600;
    color: var(--gray-800);
    margin-bottom: 4px;
    word-break: break-word;
}
.cart-quick-add-field {
    font-size: var(--font-size-sm);
}
.cart-quick-add-label {
    color: var(--gray-600);
    margin-right: 6px;
}
.cart-quick-add-label::after {
    content: ":";
}
.cart-quick-add-value {
    font-weight: 500;
    color: var(--gray-800);
    word-break: break-word;
}
.cart-quick-add-badge {
    display: inline-block;
    margin-top: 10px;
    padding: 3px 10px;
    border-radius: 12px;
    background: #f8d7da;
    color: #842029;
    font-size: var(--font-size-sm);
    font-weight: 600;
}
.cart-quick-add-qty-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 12px;
}
.cart-quick-add-dialog .dialog-buttons {
    margin-top: 12px;
}
.cart-quick-add-dialog .btn-primary:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.cart-totals-text {
    font-size: var(--font-size-sm);
    color: var(--gray-600);
    padding: var(--spacing-xs) var(--spacing-md);
    flex-shrink: 0;
}

/* Favorites / cart search boxes — right-aligned, styled like .edit-search-input. */
.favorites-search-row,
.cart-search-row {
    display: flex;
    justify-content: flex-end;
}
.cart-search-row {
    padding: 0 var(--spacing-md);
    margin-bottom: var(--spacing-xs);
    flex-shrink: 0;
}
.favorites-search-row {
    margin-bottom: var(--spacing-md);
}
.favorites-search-input,
.cart-search-input {
    padding: 7px 12px;
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    background: var(--white);
    box-sizing: border-box;
    width: 100%;
    max-width: 340px;
}
.favorites-search-input:focus,
.cart-search-input:focus {
    border-color: var(--primary);
    outline: none;
    box-shadow: 0 0 0 2px rgba(25, 135, 84, 0.15);
}

/* Type-ahead suggestion popup (assembly parent pickers). */
.asm-suggest {
    background: var(--white);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.06);
    max-height: 260px;
    overflow-y: auto;
    padding: 4px 0;
}
.asm-suggest ul { margin: 0; padding: 0; list-style: none; }
.asm-suggest li,
.asm-suggest > div {
    padding: 6px 12px;
    font-size: var(--font-size-sm);
    color: var(--gray-800);
    cursor: pointer;
    white-space: nowrap;
}
.asm-suggest li:hover,
.asm-suggest li.active,
.asm-suggest .active {
    background: rgba(25, 135, 84, 0.08);
}
.asm-suggest a,
.asm-suggest span {
    color: inherit !important;
    text-decoration: none !important;
}
.asm-suggest b { color: var(--primary); }

/* Baugruppe multi-placement cell (cart + favorites). */
.assembly-cell-line {
    font-size: var(--font-size-sm);
    color: var(--gray-800);
    line-height: 1.5;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.assembly-cell-line.asm-hoverable {
    cursor: pointer;
    text-decoration: underline dotted var(--gray-400);
    text-underline-offset: 2px;
}
.assembly-cell-line.assembly-cell-clickable {
    cursor: pointer;
    color: var(--primary);
    font-weight: 600;
}
.assembly-cell-line.assembly-cell-clickable:hover {
    text-decoration: underline;
}
.assembly-cell-more {
    font-size: var(--font-size-sm);
    color: var(--primary);
    cursor: pointer;
    line-height: 1.5;
}
.assembly-cell-more:hover { text-decoration: underline; }
.assembly-cell-popup {
    padding: 16px 20px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* Add-to-cart quantity dialog (from favorites). */
/* Class sits on the dialog root, so width applies here and the padding
   belongs to the body element. */
.favorites-qty-dialog {
    min-width: 260px;
}
.favorites-qty-dialog .body,
.favorites-qty-dialog .Wt-dialog-body {
    padding: 20px;
}
/* footer() renders as `.footer`, which the page-footer rule (green rounded
   bar) also matches; keep it part of the white card with centered buttons. */
.Wt-dialog.favorites-qty-dialog .footer {
    background: var(--white) !important;
    color: inherit !important;
    margin: 0 !important;
    border-radius: 0 !important;
    padding: 0 20px 20px !important;
    display: flex !important;
    justify-content: center !important;
    gap: var(--spacing-sm) !important;
}
.Wt-dialog.favorites-qty-dialog .footer .Wt-btn {
    margin: 0 !important;
}
.favorites-qty-name {
    display: block;
    font-weight: 600;
    font-size: var(--font-size-base);
    color: var(--gray-800);
    margin-bottom: 2px;
}
.favorites-qty-artnr {
    display: block;
    font-size: var(--font-size-sm);
    color: var(--gray-600);
    margin-bottom: 16px;
}
.favorites-qty-stepper-row {
    display: flex;
    justify-content: center;
    margin-bottom: 4px;
}

.cart-items-container {
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: auto;
    min-height: 0;
    padding: 0 var(--spacing-sm);
}

.cart-item-thumb {
    width: 50px;
    height: 50px;
    object-fit: contain;
    border-radius: var(--radius-sm);
    flex: 0 0 50px;
    cursor: pointer;
}

.cart-item-thumb:hover {
    border-color: rgba(25, 135, 84, 0.32);
    box-shadow: 0 1px 5px rgba(15, 81, 50, 0.16);
}

.cart-image-cell {
    text-align: left !important;
    vertical-align: middle !important;
}

.cart-select-cell {
    width: 42px;
    text-align: center !important;
    vertical-align: middle !important;
}

.cart-image-actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-width: 0;
    width: 100%;
    box-sizing: border-box;
}

.cart-item-thumb-empty {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 50px;
    height: 50px;
    color: var(--gray-500);
    flex: 0 0 50px;
}

.cart-detail-parts-btn {
    width: auto !important;
    min-width: 0 !important;
    max-width: 100% !important;
    min-height: 2.1em !important;
    margin: 0 !important;
    padding: 0.35em 0.7em !important;
    border-radius: var(--radius-sm) !important;
    white-space: normal;
    overflow-wrap: anywhere;
    line-height: 1.15 !important;
    box-sizing: border-box;
}

.cart-price-cell {
    color: var(--primary);
    font-weight: 700;
    font-size: 1.04em;
}

.cart-assembly-popup-btn {
    display: none !important;
}

.cart-image-popup-dialog .image-popup-container {
    min-height: 520px;
}

@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
    .Wt-dialog.cart-image-popup-dialog,
    div.Wt-dialog.cart-image-popup-dialog {
        width: 94vw !important;
        max-width: 94vw !important;
        height: 72dvh !important;
        max-height: 78dvh !important;
    }

    .cart-image-popup-dialog .image-popup-container {
        min-height: 0;
        height: calc(72dvh - 70px);
    }
}

.cart-qty-cell {
    white-space: nowrap;
    text-align: center !important;
    vertical-align: middle !important;
}

.cart-items-table th.cart-qty-cell,
.cart-items-table th.cart-select-cell,
.cart-items-table th.cart-actions-cell {
    text-align: center !important;
}

.cart-qty-align {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    width: 100%;
}

.cart-qty-stepper {
    display: inline-flex;
    align-items: stretch;
    justify-content: center;
    height: 28px;
    border: 1px solid var(--primary);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--white);
    vertical-align: middle;
    max-width: 104px;
    flex: 0 0 auto;
}

.cart-qty-btn {
    width: 28px !important;
    min-width: 28px !important;
    height: 28px !important;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: var(--primary) !important;
    color: var(--white) !important;
    font-weight: 700;
    line-height: 1;
}

.cart-qty-input {
    width: 48px !important;
    height: 28px !important;
    margin: 0;
    padding: 0 4px !important;
    border: 0 !important;
    border-left: 1px solid var(--primary) !important;
    border-right: 1px solid var(--primary) !important;
    border-radius: 0;
    text-align: center !important;
    box-sizing: border-box;
    background: var(--white) !important;
    color: var(--gray-800) !important;
    font-size: var(--font-size-sm) !important;
}

.cart-actions-cell {
    white-space: nowrap;
    text-align: center !important;
    vertical-align: middle !important;
}

.cart-actions-wrap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
}

.cart-row-action-btn {
    min-width: 54px !important;
    height: 28px !important;
    margin: 0 !important;
    padding: 0 10px !important;
    border-radius: var(--radius-sm) !important;
    box-sizing: border-box;
}

.cart-selector {
    min-width: 180px;
    height: 34px !important;
    margin: 0 !important;
    padding: 0 34px 0 12px !important;
    border: 1px solid rgba(25, 135, 84, 0.42) !important;
    border-radius: var(--radius-sm) !important;
    background-color: var(--white) !important;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--primary) 50%),
        linear-gradient(135deg, var(--primary) 50%, transparent 50%),
        linear-gradient(to right, rgba(25, 135, 84, 0.16), rgba(25, 135, 84, 0.16));
    background-position:
        calc(100% - 17px) 14px,
        calc(100% - 12px) 14px,
        calc(100% - 30px) 6px;
    background-size: 5px 5px, 5px 5px, 1px 22px;
    background-repeat: no-repeat;
    color: var(--gray-800) !important;
    font-size: var(--font-size-sm) !important;
    font-weight: 600;
    line-height: 32px !important;
    box-sizing: border-box;
    box-shadow: 0 1px 2px rgba(15, 81, 50, 0.06);
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
}
.cart-selector:focus {
    border-color: var(--primary) !important;
    box-shadow: 0 0 0 3px rgba(25, 135, 84, 0.14);
    outline: none;
}

/* Narrow viewports: cart-top-bar children stretch to full width so
   nothing gets cropped by an off-screen edge. */
@media only screen and (max-width: 480px) {
    .cart-top-bar {
        gap: 6px;
        padding: 8px;
    }
    .cart-top-bar > * {
        flex: 1 1 calc(50% - 3px);
        width: auto;
        min-width: 0;
    }
    .cart-top-action-btn {
        min-width: 0 !important;
        height: 32px !important;
        padding: 0 8px !important;
        line-height: 30px !important;
        font-size: calc(12px * var(--font-scale)) !important;
    }
    .cart-left-action-btn {
        display: none !important;
    }
    .cart-actions-menu-btn {
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        flex: 0 0 96px !important;
    }
    .cart-top-spacer {
        display: none;
    }
    .cart-top-right-actions {
        flex: 0 1 auto;
        width: auto;
        min-width: 0;
        margin-left: auto;
    }
    .cart-favorites-icon-btn {
        flex: 0 0 34px;
        width: 34px !important;
        min-width: 34px !important;
    }
    .cart-selector {
        flex: 1 1 calc(100% - 116px);
        min-width: 0;
        width: auto;
        height: 32px !important;
        line-height: 30px !important;
        padding-left: 10px !important;
        padding-right: 30px !important;
    }
    .cart-top-bar .btn-success {
        flex-basis: 34%;
    }
    .cart-top-bar .btn-danger {
        flex-basis: 34%;
    }
    .cart-top-bar .btn-outline {
        flex-basis: calc(50% - 3px);
    }
    .cart-top-bar .cart-actions-menu-btn,
    .cart-top-bar .cart-top-right-actions .btn-outline {
        flex-basis: auto;
    }
}

.cart-machine-header {
    display: block;
    padding: var(--spacing-sm) var(--spacing-lg);
    font-weight: 600;
    font-size: var(--font-size-base);
    color: var(--gray-800);
    background: var(--gray-100);
    border-bottom: 1px solid var(--gray-200);
}

/* Header row carries the bar styling so the title sits left and the
   copy-group button aligns to the right edge. */
.cart-machine-header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: linear-gradient(90deg, var(--primary-light) 0%, #f6fbf8 100%);
    border-bottom: 1px solid rgba(25, 135, 84, 0.28);
    border-left: 4px solid var(--primary);
    padding: 10px var(--spacing-lg);
    /* Group scrolls horizontally (wide table); keep title + buttons pinned. */
    position: sticky;
    left: 0;
}
.cart-machine-header-row .cart-machine-header {
    background: transparent;
    border-bottom: none;
    padding: 0;
    flex: 1;
    color: var(--gray-800);
    letter-spacing: 0;
}
.cart-group-toggle-btn {
    flex: 0 0 auto;
    width: 2em !important;
    min-width: 2em !important;
    height: 2em !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 1px solid var(--primary) !important;
    border-radius: var(--radius-sm) !important;
    background: var(--primary) !important;
    color: var(--white) !important;
    font-weight: 700 !important;
    line-height: 1 !important;
    box-shadow: 0 1px 2px rgba(15, 81, 50, 0.18) !important;
}
.cart-group-count-chip {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 3.4em;
    min-height: 2em;
    padding: 0 0.75em;
    border-radius: 999px;
    border: 1px solid rgba(25, 135, 84, 0.18);
    background: var(--white);
    color: var(--primary);
    font-size: var(--font-size-sm);
    font-weight: 700;
    white-space: nowrap;
}
.cart-copy-group-btn {
    white-space: nowrap;
}
.cart-machine-header-row .cart-copy-group-btn.btn-outline {
    border-color: rgba(25, 135, 84, 0.7) !important;
    color: var(--primary) !important;
    background: var(--white) !important;
}
.cart-machine-header-row .cart-copy-group-btn.btn-outline:hover {
    border-color: var(--primary) !important;
    background: var(--primary-light) !important;
}

.cart-machine-group {
    margin-bottom: var(--spacing-lg);
    border: 1px solid rgba(25, 135, 84, 0.20);
    border-radius: var(--radius-md);
    overflow: visible;
    box-shadow: 0 1px 3px rgba(15, 81, 50, 0.06);
}

.cart-items-table {
    width: 100%;
    border-collapse: collapse;
}

.cart-items-table th,
.cart-items-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    border-bottom: 1px solid rgba(25, 135, 84, 0.18);
    font-size: var(--font-size-sm);
    vertical-align: middle;
    text-align: left;
}

.cart-items-table th {
    background: var(--primary);
    font-weight: 600;
    color: var(--white);
    position: sticky;
    top: 0;
    z-index: 3;
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.12);
}
.cart-items-table.cart-group-collapsed tr:not(.cart-header-row) {
    display: none !important;
}
.cart-sort-header-btn {
    width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    background: transparent !important;
    color: var(--white) !important;
    font: inherit !important;
    font-weight: 700 !important;
    text-align: inherit !important;
    box-shadow: none !important;
}
.cart-sort-header-btn:hover {
    text-decoration: underline;
}

/* Fixed, uniform column widths so every machine-group table aligns vertically.
   Two variants: with the Price column (10 cols) and without (9 cols). */
.cart-machine-group .cart-items-table { table-layout: fixed; }
/* 10 columns: Select|Image|Name|ArtNr|OldArtNr|Customs|Price|Weight|Assembly|Qty */
.cart-machine-group .cart-items-table.cart-cols-price th:nth-child(1)  { width: 4%; }
.cart-machine-group .cart-items-table.cart-cols-price th:nth-child(2)  { width: 10%; }
.cart-machine-group .cart-items-table.cart-cols-price th:nth-child(3)  { width: 15%; }
.cart-machine-group .cart-items-table.cart-cols-price th:nth-child(4)  { width: 9%; }
.cart-machine-group .cart-items-table.cart-cols-price th:nth-child(5)  { width: 9%; }
.cart-machine-group .cart-items-table.cart-cols-price th:nth-child(6)  { width: 9%; }
.cart-machine-group .cart-items-table.cart-cols-price th:nth-child(7)  { width: 8%; }
.cart-machine-group .cart-items-table.cart-cols-price th:nth-child(8)  { width: 7%; }
.cart-machine-group .cart-items-table.cart-cols-price th:nth-child(9)  { width: 17%; }
.cart-machine-group .cart-items-table.cart-cols-price th:nth-child(10) { width: 12%; }
/* 9 columns (prices hidden): Select|Image|Name|ArtNr|OldArtNr|Customs|Weight|Assembly|Qty */
.cart-machine-group .cart-items-table.cart-cols-noprice th:nth-child(1)  { width: 4%; }
.cart-machine-group .cart-items-table.cart-cols-noprice th:nth-child(2)  { width: 10%; }
.cart-machine-group .cart-items-table.cart-cols-noprice th:nth-child(3)  { width: 16%; }
.cart-machine-group .cart-items-table.cart-cols-noprice th:nth-child(4)  { width: 10%; }
.cart-machine-group .cart-items-table.cart-cols-noprice th:nth-child(5)  { width: 10%; }
.cart-machine-group .cart-items-table.cart-cols-noprice th:nth-child(6)  { width: 10%; }
.cart-machine-group .cart-items-table.cart-cols-noprice th:nth-child(7)  { width: 8%; }
.cart-machine-group .cart-items-table.cart-cols-noprice th:nth-child(8)  { width: 19%; }
.cart-machine-group .cart-items-table.cart-cols-noprice th:nth-child(9)  { width: 13%; }
.cart-machine-group .cart-items-table td { overflow-wrap: break-word; }
.cart-machine-group .cart-items-table th:first-child,
.cart-machine-group .cart-items-table td:first-child,
.cart-machine-group .cart-items-table th:last-child,
.cart-machine-group .cart-items-table td:last-child {
    text-align: center !important;
    vertical-align: middle !important;
}

@media only screen and (max-width: 900px) {
    .shopping-cart-page {
        overflow: hidden;
    }

    .cart-items-container {
        padding: 0 var(--spacing-sm) var(--spacing-sm);
        overflow-y: auto;
        overflow-x: hidden;
    }

    .cart-machine-group {
        border: 0;
        border-radius: 0;
        overflow: visible;
        margin-bottom: var(--spacing-md);
        background: transparent;
    }

    .cart-machine-header-row {
        position: static;
        top: auto;
        z-index: auto;
        border: 1px solid rgba(25, 135, 84, 0.22);
        border-radius: var(--radius-md);
        margin-bottom: var(--spacing-sm);
    }

    .cart-machine-group .cart-items-table,
    .cart-machine-group .cart-items-table tbody {
        display: block;
        min-width: 0;
        width: 100%;
        clear: both;
    }

    .cart-machine-group .cart-items-table tr.cart-header-row {
        display: none;
    }

    .cart-machine-group .cart-items-table tr {
        display: grid;
        grid-template-columns: minmax(64px, 24%) minmax(0, 1fr);
        column-gap: 10px;
        row-gap: 0;
        width: 100%;
        margin-bottom: 6px;
        padding: 8px 10px;
        border: 1px solid rgba(25, 135, 84, 0.16);
        border-radius: var(--radius-md);
        background: var(--white);
        box-shadow: 0 1px 2px rgba(15, 81, 50, 0.05);
        box-sizing: border-box;
    }

    .cart-machine-group .cart-items-table td {
        display: grid;
        grid-template-columns: minmax(92px, 34%) minmax(0, 1fr);
        align-items: center;
        gap: 8px;
        width: 100% !important;
        padding: 5px 0;
        border-bottom: 1px solid rgba(25, 135, 84, 0.10);
        text-align: right !important;
        white-space: normal;
        box-sizing: border-box;
    }

    .cart-machine-group .cart-items-table td::before {
        content: attr(data-label);
        color: var(--gray-600);
        font-weight: 700;
        font-size: 0.86em;
        text-align: left;
    }

    .cart-machine-group .cart-items-table td.cart-image-cell {
        display: flex;
        grid-column: 1;
        grid-row: 2 / span 3;
        align-items: center;
        justify-content: center;
        text-align: center !important;
        border-bottom: 0;
        padding-bottom: 6px;
    }

    .cart-machine-group .cart-items-table td.cart-image-cell::before {
        content: none;
    }

    .cart-machine-group .cart-items-table tr.cart-row-no-image td.cart-image-cell {
        display: none !important;
    }

    .cart-machine-group .cart-items-table td.cart-select-cell {
        display: flex;
        grid-column: 1;
        grid-row: 1;
        align-items: center;
        justify-content: flex-start;
        text-align: left !important;
        padding: 0 0 6px;
        border-bottom: 0;
    }

    .cart-machine-group .cart-items-table td.cart-select-cell::before {
        content: none;
    }

    .cart-image-actions {
        width: 100%;
        max-width: 100%;
        align-items: center;
        justify-content: center;
        gap: 8px;
    }

    .cart-item-thumb {
        width: 56px;
        height: 44px;
        flex-basis: 56px;
    }

    .cart-item-thumb-empty {
        width: 56px;
        height: 44px;
        flex-basis: 56px;
    }

    .cart-detail-parts-btn {
        margin-left: 0 !important;
    }

    .cart-machine-group .cart-items-table td:nth-child(3) {
        display: block;
        grid-column: 2;
        grid-row: 2;
        text-align: left !important;
        font-size: 0.98em;
        padding-top: 0;
        border-bottom: 0;
        clear: both;
    }

    .cart-machine-group .cart-items-table tr.cart-row-no-image td:nth-child(3) {
        grid-column: 1 / -1;
    }

    .cart-machine-group .cart-items-table td:nth-child(3)::before {
        content: none;
    }

    .cart-machine-group .cart-items-table td.cart-artnr-cell {
        display: inline-flex;
        grid-column: 2;
        grid-row: 1;
        grid-template-columns: none;
        align-self: center;
        justify-self: start;
        align-items: baseline;
        justify-content: flex-start;
        gap: 6px;
        padding: 0 0 6px;
        border-bottom: 1px solid rgba(25, 135, 84, 0.10);
        text-align: left !important;
        font-size: 1.1em;
        font-weight: 800;
        color: var(--primary);
    }

    .cart-machine-group .cart-items-table tr.cart-row-no-image td.cart-artnr-cell {
        grid-column: 2;
    }

    .cart-machine-group .cart-items-table td.cart-artnr-cell::before {
        color: var(--primary);
        font-size: 0.8em;
        font-weight: 800;
        text-align: left;
    }

    .cart-mobile-show-more-btn {
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        margin-top: 6px !important;
        min-width: 0 !important;
        height: 24px !important;
        padding: 0 8px !important;
        font-size: calc(11px * var(--font-scale)) !important;
        line-height: 22px !important;
    }

    .cart-machine-group .cart-items-table tr.cart-mobile-details-collapsed td.cart-mobile-detail-cell {
        display: none !important;
    }

    .cart-machine-group .cart-items-table tr.cart-mobile-details-expanded td.cart-mobile-detail-cell {
        display: grid;
        grid-column: 1 / -1;
    }

    .cart-machine-group .cart-items-table td.cart-price-cell {
        color: var(--primary);
        font-weight: 800;
        font-size: 1.12em;
    }

    .cart-machine-group .cart-items-table td.cart-assembly-cell.cart-assembly-cell-has-items .cart-assembly-lines {
        display: none !important;
    }

    .cart-machine-group .cart-items-table td.cart-assembly-cell .cart-assembly-popup-btn {
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        justify-self: end;
        width: auto !important;
        min-height: 30px !important;
        padding: 0 12px !important;
        border-color: var(--primary) !important;
        color: var(--primary) !important;
        font-weight: 700 !important;
    }

    .cart-machine-group .cart-items-table td.cart-qty-cell,
    .cart-machine-group .cart-items-table td.cart-actions-cell {
        display: flex;
        grid-column: 1 / -1;
        align-items: center;
        justify-content: center;
        text-align: center !important;
        gap: 8px;
        margin-top: 4px;
        padding-top: 8px;
        border-top: 1px solid rgba(25, 135, 84, 0.10);
        border-bottom: 0;
    }

    .cart-machine-group .cart-items-table td.cart-qty-cell::before,
    .cart-machine-group .cart-items-table td.cart-actions-cell::before {
        content: none;
    }

    .cart-qty-align,
    .cart-actions-wrap {
        width: auto;
        justify-content: center;
    }

    .cart-machine-group .cart-items-table td:last-child {
        border-bottom: 0;
        padding-bottom: 0;
    }

    .cart-bottom-bar {
        align-items: stretch;
        justify-content: flex-start;
    }
}

@media only screen and (max-width: 560px) {
    .cart-top-bar {
        gap: 6px;
        padding: 6px 8px;
    }

    .cart-top-action-btn {
        min-width: 0 !important;
        height: 30px !important;
        padding: 0 8px !important;
        line-height: 28px !important;
        font-size: calc(12px * var(--font-scale)) !important;
    }
    .cart-left-action-btn {
        display: none !important;
    }
    .cart-actions-menu-btn {
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        flex: 0 0 96px !important;
    }

    .cart-selector {
        min-width: 0;
        height: 30px !important;
        line-height: 28px !important;
        padding-left: 10px !important;
        padding-right: 30px !important;
    }

    .cart-favorites-icon-btn {
        flex: 0 0 32px;
        width: 32px !important;
        min-width: 32px !important;
        height: 30px !important;
    }

    .cart-top-spacer {
        display: none;
    }

    .cart-top-right-actions {
        flex: 0 1 auto;
        width: auto;
        min-width: 0;
        gap: 6px;
        margin-left: auto;
    }

    .cart-totals-text {
        padding: 2px 8px;
        font-size: calc(12px * var(--font-scale));
    }

    .cart-search-row {
        padding: 0 8px;
        margin-bottom: 4px;
    }

    .cart-search-input {
        height: 30px;
        font-size: calc(12px * var(--font-scale));
    }

    .cart-machine-header-row {
        align-items: center;
        flex-direction: row;
        flex-wrap: wrap;
        gap: 6px;
        padding: 8px 10px;
    }

    .cart-machine-header-row .cart-machine-header {
        flex: 1 1 0;
        min-width: 0;
        font-size: var(--font-size-sm);
    }

    .cart-group-toggle-btn {
        width: 28px !important;
        min-width: 28px !important;
        height: 28px !important;
    }

    .cart-group-count-chip {
        min-height: 28px;
        min-width: 0;
        padding: 0 0.6em;
    }

    .cart-copy-group-btn {
        flex: 1 1 calc(50% - 3px);
        width: auto;
        min-width: 0 !important;
        height: 28px !important;
        padding: 0 8px !important;
        font-size: calc(12px * var(--font-scale)) !important;
        line-height: 26px !important;
    }

    .cart-machine-group .cart-items-table td {
        grid-template-columns: minmax(82px, 31%) minmax(0, 1fr);
        gap: 6px;
        padding: 4px 0;
        font-size: calc(12px * var(--font-scale));
        text-align: right !important;
    }

    .cart-machine-group .cart-items-table td::before {
        margin-bottom: 0;
        font-size: 0.78em;
    }

    .cart-machine-group .cart-items-table td.cart-image-cell,
    .cart-machine-group .cart-items-table td.cart-select-cell,
    .cart-machine-group .cart-items-table td:nth-child(3) {
        text-align: left !important;
    }

    .cart-machine-group .cart-items-table td.cart-qty-cell,
    .cart-machine-group .cart-items-table td.cart-actions-cell {
        align-items: center;
        flex-direction: row;
    }

    .cart-qty-align,
    .cart-actions-wrap {
        justify-content: center;
    }

    .cart-actions-wrap {
        width: 100%;
    }

    .cart-row-action-btn {
        flex: 1 1 0;
    }

    .cart-bottom-bar .cart-total-price,
    .cart-bottom-bar .cart-total-weight {
        flex: 1 1 100%;
        margin-right: 0;
    }

    .cart-bottom-bar button {
        flex: 1 1 100%;
        width: 100%;
    }

    .cart-detail-parts-dialog {
        width: calc(100vw - 24px) !important;
    }

    .cart-detail-parts-table th:nth-child(6),
    .cart-detail-parts-table td:nth-child(6) {
        display: none;
    }
}

/* Shopping cart touch layout: preserve the scrollable item area first.
   This catches phones whose visual viewport does not land in the narrow px
   breakpoints and keeps the top/bottom controls from eating the page. */
@media only screen and (max-width: 900px), (hover: none) and (pointer: coarse) {
    .shopping-cart-page,
    .shopping-cart-page > div,
    .shopping-cart-page > .Wt-stack,
    .shopping-cart-page > .Wt-stack > div {
        min-height: 0;
        overflow: hidden;
    }

    .cart-top-bar {
        display: flex !important;
        align-items: center;
        flex-wrap: wrap;
        gap: 5px !important;
        padding: 5px 8px !important;
    }

    .cart-left-action-btn {
        display: none !important;
    }

    .cart-actions-menu-btn {
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        flex: 0 0 auto !important;
        min-width: 76px !important;
        width: auto !important;
        height: 28px !important;
        padding: 0 10px !important;
        line-height: 26px !important;
        font-size: calc(12px * var(--font-scale)) !important;
    }

    .cart-selector {
        flex: 1 1 132px !important;
        min-width: 112px !important;
        max-width: none !important;
        height: 28px !important;
        padding-top: 0 !important;
        padding-bottom: 0 !important;
        line-height: 26px !important;
        background-position:
            calc(100% - 17px) 11px,
            calc(100% - 12px) 11px,
            calc(100% - 30px) 4px;
        background-size: 5px 5px, 5px 5px, 1px 20px;
    }

    .cart-top-spacer {
        display: none !important;
    }

    .cart-top-right-actions {
        flex: 0 1 auto !important;
        width: auto !important;
        margin-left: auto !important;
        gap: 5px !important;
        justify-content: flex-end;
    }

    .cart-favorites-icon-btn {
        flex: 0 0 28px !important;
        width: 28px !important;
        min-width: 28px !important;
        height: 28px !important;
    }

    .cart-favorites-icon-btn::before {
        width: 15px;
        height: 15px;
    }

    .cart-top-right-actions .btn-outline {
        min-width: 0 !important;
        height: 28px !important;
        padding: 0 9px !important;
        line-height: 26px !important;
        font-size: calc(12px * var(--font-scale)) !important;
    }

    .cart-totals-text {
        padding: 2px 8px !important;
        font-size: calc(11px * var(--font-scale)) !important;
        line-height: 1.25;
    }

    .cart-search-row {
        padding: 0 8px !important;
        margin-bottom: 3px !important;
    }

    .cart-search-input {
        max-width: none;
        height: 28px !important;
        padding-top: 0 !important;
        padding-bottom: 0 !important;
        line-height: 26px !important;
    }

    .cart-items-container {
        flex: 1 1 auto !important;
        min-height: 0 !important;
        overflow-y: auto !important;
        overflow-x: hidden !important;
        -webkit-overflow-scrolling: touch;
        padding: 0 6px 6px !important;
    }

    .cart-machine-header-row {
        position: static !important;
        top: auto !important;
        z-index: auto !important;
        gap: 5px !important;
        padding: 6px 8px !important;
        margin-bottom: 5px !important;
        border-radius: 5px !important;
    }

    .cart-machine-group .cart-items-table {
        margin-top: 0 !important;
        clear: both !important;
    }

    .cart-group-toggle-btn {
        width: 26px !important;
        min-width: 26px !important;
        height: 26px !important;
    }

    .cart-group-count-chip {
        min-height: 24px !important;
        padding: 0 8px !important;
        font-size: calc(11px * var(--font-scale)) !important;
    }

    .cart-copy-group-btn {
        height: 26px !important;
        min-height: 26px !important;
        padding: 0 8px !important;
        line-height: 24px !important;
        font-size: calc(11px * var(--font-scale)) !important;
    }

    .cart-machine-group .cart-items-table tr {
        margin-bottom: 5px !important;
        padding: 6px 8px !important;
        row-gap: 0 !important;
        border-radius: 5px !important;
    }

    .cart-machine-group .cart-items-table td {
        padding: 3px 0 !important;
        font-size: calc(12px * var(--font-scale)) !important;
    }

    .cart-machine-group .cart-items-table td.cart-qty-cell,
    .cart-machine-group .cart-items-table td.cart-actions-cell {
        margin-top: 2px !important;
        padding-top: 5px !important;
    }

    .cart-bottom-bar {
        position: sticky;
        bottom: 0;
        z-index: 20;
        display: grid !important;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: center !important;
        gap: 5px !important;
        padding: 6px 8px calc(6px + env(safe-area-inset-bottom)) !important;
        border-radius: 5px 5px 0 0 !important;
        border-top-width: 2px !important;
        box-shadow: 0 -4px 12px rgba(15, 81, 50, 0.10);
    }

    .cart-bottom-bar .cart-total-price,
    .cart-bottom-bar .cart-total-weight {
        grid-column: auto;
        flex: 0 1 auto !important;
        margin: 0 !important;
        font-size: calc(12px * var(--font-scale)) !important;
        line-height: 1.2;
    }

    .cart-bottom-bar .cart-total-price:empty,
    .cart-bottom-bar .cart-total-weight:empty {
        display: none !important;
    }

    .cart-bottom-bar .cart-total-weight:first-child,
    .cart-bottom-bar .cart-total-price:first-child {
        grid-column: 1 / -1;
    }

    .cart-bottom-bar button {
        flex: 1 1 auto !important;
        width: auto !important;
        min-width: 0 !important;
        height: 30px !important;
        padding: 0 8px !important;
        line-height: 28px !important;
        font-size: calc(12px * var(--font-scale)) !important;
    }
}

/* Mobile dialogs should still feel like popups. Earlier mobile rules made every
   Wt dialog fullscreen to protect long editors, but small actions such as
   Add-to-cart then opened like a blank page. This later contract keeps dialogs
   centered, compact, and scrollable within the card. */
@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
    body div.Wt-dialog,
    .Wt-dialog {
        position: fixed !important;
        top: 50% !important;
        left: 50% !important;
        right: auto !important;
        bottom: auto !important;
        width: min(92vw, 460px) !important;
        min-width: 0 !important;
        max-width: 92vw !important;
        height: auto !important;
        min-height: 0 !important;
        max-height: 88vh !important; /* fallback for browsers without dvh */
        max-height: min(88dvh, 720px) !important;
        margin: 0 !important;
        padding: 0 !important;
        transform: translate(-50%, -50%) !important;
        display: flex !important;
        flex-direction: column !important;
        border-radius: 10px !important;
        overflow: hidden !important;
    }

    /* .dialog-layout is the wrapper this Wt version actually renders
       (.Wt-dialog > .dialog-layout > (.titlebar, .body)); the other two
       are version fallbacks. Without flex sizing here the wrapper grows
       past the dialog's max-height and the body never scrolls. */
    .Wt-dialog > .dialog-layout,
    .Wt-dialog > .Wt-dialog-contents,
    .Wt-dialog > .contents {
        display: flex !important;
        flex: 1 1 auto !important;
        flex-direction: column !important;
        min-height: 0 !important;
        max-height: inherit !important;
        overflow: hidden !important;
    }

    .Wt-dialog .titlebar,
    .Wt-dialog .Wt-dialog-title-bar {
        flex: 0 0 auto !important;
        padding: 10px 42px 10px 14px !important;
        font-size: calc(14px * var(--font-scale)) !important;
        line-height: 1.2 !important;
    }

    .Wt-dialog .closeicon {
        top: 7px !important;
        right: 10px !important;
        width: 26px !important;
        height: 26px !important;
        font-size: calc(24px * var(--font-scale)) !important;
        line-height: 26px !important;
    }

    .Wt-dialog .body,
    .Wt-dialog .Wt-dialog-body {
        flex: 1 1 auto !important;
        min-height: 0 !important;
        max-height: none !important;
        overflow-y: auto !important;
        overflow-x: hidden !important;
        padding: 12px !important;
        -webkit-overflow-scrolling: touch;
    }

    .Wt-dialog .Wt-dialog-footer,
    .Wt-dialog .Wt-msgbox-buttons {
        flex: 0 0 auto !important;
        padding: 10px 12px !important;
        display: flex !important;
        flex-wrap: wrap !important;
        gap: 8px !important;
        justify-content: flex-end !important;
    }

    .Wt-dialog .Wt-dialog-footer button,
    .Wt-dialog .Wt-dialog-footer .pdf-btn,
    .Wt-dialog .Wt-msgbox-buttons button {
        flex: 1 1 0 !important;
        min-width: 96px !important;
        height: 34px !important;
        margin: 0 !important;
        padding: 0 12px !important;
        line-height: 32px !important;
    }

    .add-cart-dialog,
    .bom-bulk-add-dialog,
    .favorites-qty-dialog,
    .column-selector-dialog {
        width: min(92vw, 420px) !important;
        max-height: min(82dvh, 560px) !important;
    }

    /* "Item added to cart" success card only. Its native titlebar duplicates
       the checkmark title already shown in the body, so keep both compact.
       Scoped to .cart-added-dialog: .cart-dialog alone is shared by the wider
       cart popups (new/rename/delete/move/detail parts), which need the
       generic sizing above. */
    .cart-added-dialog {
        width: min(92vw, 380px) !important;
        max-height: min(80dvh, 480px) !important;
    }

    .cart-added-dialog .titlebar,
    .cart-added-dialog .Wt-dialog-title-bar {
        padding: 8px 34px 8px 12px !important;
        font-size: calc(13px * var(--font-scale)) !important;
    }

    .cart-added-dialog .body,
    .cart-added-dialog .Wt-dialog-body {
        padding: 12px 14px !important;
        font-size: 0.92em !important;
    }

    /* First direct child of the body is the image+info row (inline
       display:flex;gap:16px;margin-bottom:16px from the C++ side). */
    .cart-added-dialog .body > div:first-child {
        gap: 12px !important;
        margin-bottom: 10px !important;
    }

    .cart-added-dialog .btn-primary {
        min-width: 140px !important;
        height: 38px !important;
    }

    .bom-bulk-add-dialog .bom-bulk-add-image-cell {
        width: 36px;
        min-width: 36px;
    }

    .bom-bulk-add-image {
        max-width: 28px;
        width: 28px;
        height: auto;
    }

    .bom-bulk-add-dialog .bom-bulk-add-scroll {
        overflow-x: hidden;
    }

    .bom-bulk-add-dialog .add-cart-qty-stepper {
        flex-wrap: nowrap;
        height: 28px;
    }

    .bom-bulk-add-dialog .add-cart-qty-stepper .add-cart-qty-btn {
        width: 26px;
        height: 28px;
    }

    .bom-bulk-add-dialog .add-cart-qty-stepper .add-cart-qty-input {
        width: 40px;
        min-width: 0;
        height: 28px;
    }

    .edit-dialog-lg,
    .order-details-dialog,
    .large-dialog,
    .import-price-dialog,
    .part-details-manager-dialog,
    .threejs-viewer-popup,
    .image-popup-dialog,
    /* Wide admin/viewer dialogs: same 96vw treatment as the rest of this list. */
    .pdf-file-viewer,
    .part-details-import-dialog,
    .retrofit-csv-import-dialog,
    .incoming-links-dialog,
    .audit-detail-dialog,
    .image-viewer-popup {
        width: 96vw !important;
        max-width: 96vw !important;
        max-height: 92dvh !important;
    }

    .add-cart-info-row {
        gap: 12px;
    }

    .add-cart-qty-row {
        margin-top: 8px;
        gap: 10px;
    }

    .add-cart-qty-stepper {
        height: 32px;
    }

    .add-cart-qty-stepper .add-cart-qty-btn {
        width: 32px;
        height: 32px;
    }

    .add-cart-qty-stepper .add-cart-qty-input {
        height: 32px;
    }
}

/* ================================================================
   DIALOG FORM HELPERS
   ================================================================ */

.cart-dialog-content {
    padding: var(--spacing-lg);
}

.cart-detail-parts-dialog .Wt-dialog-contents {
    overflow: visible !important;
}

.cart-detail-parts-content {
    max-height: 70vh;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: var(--spacing-lg);
    box-sizing: border-box;
    overflow: hidden;
}

.cart-detail-parts-scroll {
    flex: 1 1 auto;
    min-height: 120px;
    overflow: auto;
}

.cart-detail-parts-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}

.cart-detail-parts-table th,
.cart-detail-parts-table td {
    padding: 8px 10px;
    border-bottom: 1px solid var(--gray-200);
    vertical-align: middle;
}

.cart-detail-parts-table th {
    background: var(--gray-100);
    color: var(--gray-600);
    font-weight: 700;
}

.cart-detail-parts-table th:nth-child(1) { width: 42px; text-align: center; }
.cart-detail-parts-table th:nth-child(2) { width: 54px; text-align: center; }
.cart-detail-parts-table th:nth-child(3) { width: 20%; }
.cart-detail-parts-table th:nth-child(4) { width: auto; }
.cart-detail-parts-table th:nth-child(5) { width: 72px; text-align: center; }
.cart-detail-parts-table th:nth-child(6) { width: 130px; }

.cart-detail-parts-table td:nth-child(1),
.cart-detail-parts-table td:nth-child(2),
.cart-detail-parts-table td:nth-child(5) {
    text-align: center;
}

.cart-detail-parts-image-cell {
    padding-left: 4px !important;
    padding-right: 4px !important;
}

.cart-detail-parts-image {
    width: 34px;
    height: 34px;
    object-fit: contain;
    border-radius: 3px;
    background: #f8f9fa;
    vertical-align: middle;
}

.cart-detail-part-existing {
    color: #856404;
    font-weight: 600;
}

.cart-detail-part-new {
    color: var(--primary);
    font-weight: 600;
}

.dialog-input-full {
    width: 100%;
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-base);
}

.dialog-field-label {
    margin-top: var(--spacing-md);
    margin-bottom: var(--spacing-xs);
    font-weight: 500;
    color: var(--gray-700);
}

.dialog-checkbox {
    display: block;
    margin-top: var(--spacing-sm);
}

/* ================================================================
   SMALL & OUTLINE BUTTONS
   ================================================================ */

.btn-sm {
    padding: var(--spacing-xs) var(--spacing-md);
    font-size: var(--font-size-sm);
}

.btn-outline {
    background: transparent;
    border: 1px solid var(--gray-600);
    color: var(--gray-600);
    border-radius: var(--radius-sm);
    cursor: pointer;
    margin-left: var(--spacing-xs);
    padding: var(--spacing-xs) var(--spacing-md);
    font-size: var(--font-size-sm);
    transition: all var(--transition-fast);
}

.btn-outline:hover {
    background: var(--gray-600);
    color: var(--white);
}

/* ================================================================
   SETTINGS PAGE
   ================================================================ */

.settings-page {
    padding: var(--spacing-lg);
    /* Clearance so the last content is not hidden behind the fixed footer. */
    padding-bottom: 72px;
    width: 100%;
    max-width: 100%;
    /* Flows as one document; the page (content-container) is the single scroll. */
    box-sizing: border-box;
}

.settings-page h2 {
    display: none;
}

/* Settings tabs: full Wt tab styling */
.settings-tabs {
    width: 100%;
    display: flex;
    flex-direction: column;
}

/* CustomTabs: app-controlled tab widget (replaces Wt's WTabWidget styling).
   Flex column: tab bar fixed at top, stack fills remaining space and scrolls
   internally. Requires parent to give height (e.g. .settings-page is
   height:100%). */
.ctabs {
    width: 100%;
    min-width: 0;
}

.ctabs-bar {
    display: flex;
    align-items: stretch;
    gap: var(--spacing-lg);
    padding: 0 var(--spacing-lg);
    margin: 0;
    border-bottom: 1px solid var(--gray-300);
    background: var(--white);
    position: sticky;
    top: 0;
    z-index: 2;
    overflow-x: auto;
    overflow-y: hidden;
    flex-wrap: nowrap;
    scrollbar-width: thin;
}

.ctabs-bar::-webkit-scrollbar { height: 6px; }
.ctabs-bar::-webkit-scrollbar-thumb { background: var(--gray-300); border-radius: 3px; }

.ctabs-bar .ctabs-tab {
    appearance: none;
    -webkit-appearance: none;
    display: inline-flex;
    align-items: center;
    padding: var(--spacing-md);
    margin: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    background-image: none;
    color: var(--gray-700);
    font-family: inherit;
    font-size: var(--font-size-base);
    font-weight: 500;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    box-shadow: none;
    flex: 0 0 auto;
    white-space: nowrap;
    transition: color var(--transition-fast),
                box-shadow var(--transition-fast);
}

.ctabs-bar .ctabs-tab:hover {
    color: var(--primary-dark);
    background: transparent;
    box-shadow: inset 0 -2px 0 var(--gray-400);
}

.ctabs-bar .ctabs-tab:focus,
.ctabs-bar .ctabs-tab:focus-visible {
    outline: none;
}

.ctabs-bar .ctabs-tab--active,
.ctabs-bar .ctabs-tab--active:hover {
    color: var(--primary);
    font-weight: 600;
    background: transparent;
    box-shadow: inset 0 -3px 0 var(--primary);
}

.ctabs-stack {
    padding: var(--spacing-lg);
    background: var(--white);
    min-width: 0;
}

/* Search-page tab wrapper: chip bar stays above, tab bar + sections below. */
.search-tabs-wrapper {
    margin-top: var(--spacing-md);
}

.settings-tab-content {
    padding: var(--spacing-sm);
    min-width: 0;
    max-width: 100%;
}

.settings-group {
    margin-bottom: var(--spacing-xl);
}

.settings-group legend {
    font-weight: 600;
    color: var(--primary);
    font-size: var(--font-size-lg);
    padding: 0 var(--spacing-sm);
}

/* Import tab: plain container + heading text per section (no WGroupBox —
   its children render invisible on live deploy in this project). */
.settings-import-section {
    margin-bottom: var(--spacing-xl);
}

.settings-import-section-title {
    display: block;
    font-weight: 600;
    color: var(--primary);
    font-size: var(--font-size-lg);
    margin-bottom: var(--spacing-sm);
}

.settings-import-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-sm);
}

.settings-import-row .edit-input {
    min-width: 260px;
}

/* Rabat import diff preview: status-tinted summary blocks and table rows. */
.rabat-diff-block {
    border-radius: var(--radius-sm);
    padding: var(--spacing-sm) var(--spacing-md);
    margin-bottom: var(--spacing-sm);
}

.rabat-diff-block-added {
    background: var(--primary-light);
    color: var(--primary-dark);
    border: 1px solid var(--primary);
}

.rabat-diff-block-changed {
    background: #fff3cd;
    color: #856404;
    border: 1px solid var(--warning);
}

.rabat-diff-block-deleted {
    background: #f8d7da;
    color: #721c24;
    border: 1px solid var(--danger);
}

.rabat-diff-added { background: var(--primary-light) !important; }
.rabat-diff-added:hover { background: #c8e6c9 !important; }

.rabat-diff-changed { background: #fff3cd !important; }
.rabat-diff-changed:hover { background: #ffe8a1 !important; }

.rabat-diff-deleted { background: #f8d7da !important; }
.rabat-diff-deleted:hover { background: #f1b0b7 !important; }

.rabat-diff-unchanged { background: transparent; }

.table-scroll-wrapper {
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
}

.table-scroll-wrapper > .edit-assembly-table,
.table-scroll-wrapper > .edit-parts-table {
    min-width: 720px;
    width: 100%;
}

/* machine-table fits its container instead of forcing horizontal overflow:
   with hundreds of rows the wrapper's horizontal scrollbar renders at the
   bottom of the table and becomes unreachable. */
.table-scroll-wrapper > .machine-table {
    min-width: 0;
    width: 100%;
}

/* Import preview tables (Artikel/Conversion/Discount): basic borders and
   a width floor so the inline scroll wrappers actually scroll. */
.conv-preview-table {
    border-collapse: collapse;
    width: 100%;
    min-width: 560px;
}
.conv-preview-table th,
.conv-preview-table td {
    border: 1px solid var(--gray-300);
    padding: 4px 8px;
    text-align: left;
    font-size: var(--font-size-sm);
}
.conv-preview-table th {
    background: var(--gray-100);
    position: sticky;
    top: 0;
}

@media only screen and (max-width: 768px) {
    .settings-page {
        padding: var(--spacing-sm);
        overflow-x: hidden !important;
    }
    .settings-tabs {
        max-width: 100%;
        min-width: 0;
        overflow-x: hidden;
    }
    .ctabs-bar {
        flex-wrap: nowrap;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        white-space: nowrap;
        max-width: 100%;
        gap: var(--spacing-md);
        padding: 0 var(--spacing-sm);
    }
    .ctabs-bar .ctabs-tab {
        flex: 0 0 auto;
        padding: var(--spacing-sm) var(--spacing-xs);
        font-size: var(--font-size-sm);
    }
    .ctabs-stack {
        padding: var(--spacing-sm) var(--spacing-md);
        overflow: auto;
        max-width: 100%;
        -webkit-overflow-scrolling: touch;
    }
    .settings-tab-content {
        padding: var(--spacing-xs);
        max-width: 100%;
        overflow-x: hidden;
    }
    .settings-admin-content {
        padding: 0 !important;
        max-width: 100%;
        overflow-x: hidden;
    }

    .edit-assembly-page,
    .edit-page {
        max-width: 100%;
        overflow-x: hidden;
    }

    .table-scroll-wrapper > .edit-assembly-table,
    .table-scroll-wrapper > .edit-parts-table {
        min-width: 600px;
    }
}

/* ============================================
   MACHINE-TABLE MOBILE CARDS
   Shared by 11 settings tables (companies, machines,
   maintenance x2, retrofit x2, deleted parts, import
   history x4) with different column counts, so every
   rule here is column-count agnostic (no nth-child).
   Wt's WTable never wraps rows in <thead>/<tbody> —
   setHeaderCount() only swaps <td> for <th> in the
   header row — so table/tr/td display is reset
   together here. Flipping only td to block/grid while
   its tr stays table-row produces an anonymous table
   wrapper box that renders as a blank cell.
   Labels come from data-label (set in C++ via
   EditorHelpers::applyMobileLabels), which is omitted
   for empty-header columns and colspan cells.
   The 1024px gate is wider than the usual mobile one:
   the widest of these tables (retrofit kits, 10 cols)
   needs ~915px to seat every column plus the actions
   buttons, so below that it must become cards rather
   than clip the Delete button.
   ============================================ */
@media only screen and (max-width: 1024px) {
    .machine-table { display: block; }
    .machine-table thead, .machine-table tbody { display: block; }
    .machine-table tr:has(th) { display: none; }

    .machine-table tr {
        display: grid;
        grid-template-columns: 1fr;
        border: 1px solid var(--gray-300);
        border-radius: var(--radius-md);
        margin-bottom: var(--spacing-sm);
        padding: var(--spacing-sm) var(--spacing-md);
        background: var(--white);
    }

    .machine-table td {
        display: grid;
        grid-template-columns: minmax(88px, 40%) minmax(0, 1fr);
        gap: var(--spacing-sm);
        align-items: center;
        width: auto;
        /* A card cell spans the card, so the desktop column-fitting limits
           must not apply; `anywhere` would also split short labels (DE, FR). */
        max-width: none;
        min-width: 0;
        overflow-wrap: break-word;
        padding: 4px 0;
        border-bottom: 1px solid var(--gray-100);
        white-space: normal;
    }
    .machine-table td:last-child { border-bottom: 0; }

    .machine-table td::before {
        content: attr(data-label);
        font-weight: 700;
        color: var(--gray-600);
        font-size: var(--font-size-sm);
    }

    /* Cells with no data-label: empty-header columns, or the colspan
       empty-state row ("no results"). No label column reserved for these. */
    .machine-table td:not([data-label]) {
        display: block;
        text-align: center;
    }
    .machine-table td:not([data-label])::before {
        content: none;
    }

    .machine-table td:has(> .actions-container) {
        width: auto;
        white-space: normal;
    }

    /* Grid items stretch by default, which would pull a pill badge across the
       whole value column. */
    .machine-table td > .badge,
    .machine-table td > .actions-container {
        justify-self: start;
    }
    .machine-table .actions-container {
        flex-wrap: wrap;
    }

    /* .multi-lang carries a 220px floor for the auto-layout table columns.
       Inside a card the value column is already constrained, and the floor
       would push the card past the viewport. */
    .machine-table td .multi-lang {
        min-width: 0 !important;
        max-width: none !important;
    }
}

/* ============================================
   IMPORT HISTORY & AUTOMATION
   (ui/dialogs/importhistorypanel.{h,cpp} — Automation / Import runs /
   Compare sub-tab: card sections, status/compare pill badges, counts
   emphasis, sub-tables for the row-level change log.)
   ============================================ */

/* Card wrapper for each of the 3 sub-tab sections. Mirrors .machine-card's
   white/border/shadow language instead of the plain settings-import-section
   heading-only look. */
.imphist-card {
    background: var(--white);
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-lg);
    box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
    padding: var(--spacing-lg);
}

.imphist-card .settings-import-section-title {
    margin: 0 0 var(--spacing-md) 0;
    padding-bottom: var(--spacing-sm);
    border-bottom: 1px solid var(--gray-200);
}

/* Status pill badges: run status (applied/pending/error) and compare
   summary counts (added/changed/deleted) share the same 3-color palette. */
.imphist-badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: var(--font-size-sm);
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}

.imphist-badge--applied { background: var(--primary-light); color: var(--primary-dark); }
.imphist-badge--pending { background: #fff3cd; color: #856404; }
.imphist-badge--error   { background: #f8d7da; color: #721c24; }

.imphist-compare-summary {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    margin-top: var(--spacing-sm);
}

/* Runs table counts column: 4 segments separated by a hairline, zero
   values muted, changed/deleted emphasized when non-zero. */
.imphist-counts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
}

.imphist-cnt {
    font-size: var(--font-size-sm);
    color: var(--gray-700);
    padding: 0 8px;
}

.imphist-cnt:first-child {
    padding-left: 0;
}

.imphist-cnt:not(:first-child) {
    border-left: 1px solid var(--gray-300);
}

.imphist-cnt--changed { color: #856404; font-weight: 600; }
.imphist-cnt--deleted { color: #721c24; font-weight: 600; }
.imphist-cnt--muted   { color: var(--gray-500); }

/* Automation box progress/status text, shaped as an inline pill instead of
   the full-width block .status-text normally renders. */
.imphist-status-chip {
    display: inline-block;
    border-radius: 999px;
    padding: 4px 12px;
    font-size: var(--font-size-sm);
}

/* Expanded run row hosting the details breakdown + change log: indented
   and tinted to read as a nested panel under the main runs row. */
.imphist-details-cell {
    padding: 10px 16px 14px 28px;
    background: #fafafa;
    border-bottom: 1px solid #eee;
}

/* Sub-tables (details breakdown, change log) inside an expanded run row:
   lighter/smaller header than the main machine-table so they read as
   subordinate. Header background/color is set inline in C++
   (styleSubHeaderCell) since machine-table headers use inline styles that
   a CSS class alone cannot override; this rule covers layout/spacing. */
.imphist-subtable {
    margin-top: 4px;
}

.imphist-subtable th {
    font-size: var(--font-size-sm);
    background: var(--gray-100);
}

.settings-admin-content {
    padding: var(--spacing-sm) 0;
    overflow-x: hidden;
}

.settings-mail-grid {
    display: grid;
    grid-template-columns: 140px 1fr;
    gap: var(--spacing-sm);
    align-items: center;
    max-width: 500px;
}

.settings-mail-grid .dialog-input-full {
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-base);
}

.settings-mail-actions {
    margin-top: var(--spacing-lg);
}

.settings-save-status {
    margin-left: var(--spacing-md);
    color: var(--primary);
    font-weight: 500;
}

.settings-role-table {
    border-collapse: collapse;
    margin-top: var(--spacing-sm);
    width: 100%;
}

.settings-role-table th,
.settings-role-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    text-align: left;
    border-bottom: 1px solid var(--gray-200);
}

.settings-role-table tr:nth-child(even) {
    background: var(--gray-100);
}

.settings-role-table th {
    background: var(--gray-100);
    font-weight: 600;
    color: var(--gray-700);
}

.settings-role-note {
    margin-top: var(--spacing-md);
    color: var(--gray-600);
    font-size: var(--font-size-sm);
}

/* Action button plus its status line, above a settings table. Wraps so the
   status text drops below the button on narrow screens instead of squeezing. */
.settings-actions-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-sm);
}

/* The note inside this row is inline, so it must not add the block spacing. */
.settings-actions-row .settings-role-note {
    margin-top: 0;
}

/* ================================================================
   ORDER MANAGEMENT ADDITIONS
   ================================================================ */

.order-machine-header {
    display: block;
    padding: var(--spacing-sm) var(--spacing-lg);
    font-weight: 600;
    font-size: var(--font-size-base);
    color: var(--primary);
    background: var(--primary-light);
    border-bottom: 1px solid var(--gray-200);
    margin-top: var(--spacing-md);
    border-radius: var(--radius-sm);
}


/* ================================================================
   SECTION NAVIGATION BUTTONS (in secondary nav bar)
   ================================================================ */

.homepage-section-btn {
    padding: var(--spacing-xs) var(--spacing-lg);
    border: 2px solid var(--primary);
    border-radius: var(--radius-md);
    background: var(--white);
    color: var(--primary);
    font-weight: 600;
    font-size: var(--font-size-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
    white-space: nowrap;
}

.homepage-section-btn:hover {
    background: var(--primary-light);
}

.homepage-section-btn.active {
    background: var(--primary);
    color: var(--white);
}

/* ================================================================
   MAINTENANCE PAGE
   ================================================================ */

/* Flows as one document; content-container is the single scroll (see
   SparePartsPage::showMaintenancePage). No height and no overflow here:
   the page is mounted below a back bar, so a height:100% box would start
   that far down and its bottom would be cut off by content-container's
   overflow:hidden, putting the last rows out of reach of any scrollbar. */
.maintenance-page {
    padding: var(--spacing-lg);
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}

/* Mode panels. The root carries spacing only: its display is written by
   setHidden(), so nothing else may occupy that property. Arrangement sits on
   the inner .maint-col / .maint-row wrappers, in CSS rather than a Wt layout
   manager — a layout manager measures its container in JavaScript and gives
   its children zero size when that container is display:none at first render,
   leaving the panel empty once it is shown. */
.maintenance-mode-panel {
    margin-top: 4px;
}

.maint-col {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.maint-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.maint-field-label {
    flex: 0 0 140px;
}

.maint-field-input {
    flex: 1 1 200px;
    min-width: 0;
    padding: 6px 10px;
    border: 1px solid #ced4da;
    border-radius: 4px;
}

/* Machine-number picker trigger (customers without internal.content). Styled
   like .maint-field-input; the global .Wt-btn rule centres content with
   !important, hence the overrides. */
.maint-machine-trigger.Wt-btn {
    position: relative;
    flex: 1 1 200px;
    min-width: 0;
    min-height: 34px;
    margin: 0 !important;
    padding: 6px 30px 6px 10px !important;
    justify-content: flex-start !important;
    text-align: left !important;
    border: 1px solid #ced4da !important;
    border-radius: 4px !important;
    background: var(--white) !important;
    color: var(--gray-800) !important;
    font-weight: 400;
    box-shadow: none !important;
}
.maint-machine-trigger.Wt-btn::after {
    content: "\25BE";
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    font-size: calc(13px * var(--font-scale));
}
.maint-machine-trigger.Wt-btn:disabled {
    background: #f8f9fa !important;
    color: #6c757d !important;
    cursor: not-allowed;
}
.maint-machine-empty-hint {
    flex: 1 1 100%;
    font-size: 0.9em;
    color: #6c757d;
}

.maint-checks-box {
    padding: 10px 12px;
    border: 1px solid #dee2e6;
    border-radius: 4px;
    background: #f8f9fa;
}

/* Placeholder state, before an engine code selects the real field list. */
.maint-checks-box.is-hint {
    padding: 8px;
    border-style: dashed;
    font-size: 0.9em;
    color: #6c757d;
}

/* ================================================================
   RETROFIT KIT PAGE
   ================================================================ */

/* Flows as one document; content-container is the single scroll (see
   SparePartsPage::showRetrofitPage). No height and no overflow here:
   the page is mounted below a back bar, so a height:100% box would start
   that far down and its bottom would be cut off by content-container's
   overflow:hidden, putting the last rows out of reach of any scrollbar. */
.retrofit-page {
    padding: var(--spacing-xl);
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}

.retrofit-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--spacing-xl);
}

.retrofit-card {
    background: var(--white);
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: all var(--transition-base);
    cursor: pointer;
}

.retrofit-card:hover {
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.12);
    transform: translateY(-2px);
}

.retrofit-card-image {
    width: 100%;
    height: 180px;
    object-fit: cover;
    background: var(--gray-100);
}

.retrofit-card-body {
    padding: var(--spacing-lg);
}

.retrofit-card-title {
    font-weight: 600;
    font-size: var(--font-size-lg);
    color: var(--gray-800);
    margin-bottom: var(--spacing-sm);
}

.retrofit-card-desc {
    font-size: var(--font-size-sm);
    color: var(--gray-600);
    margin-bottom: var(--spacing-md);
}

.retrofit-card-meta {
    font-size: var(--font-size-xs);
    color: var(--gray-500);
}

.retrofit-detail-page {
    height: 100%;
    overflow-y: auto;
    padding: var(--spacing-xl);
}

.retrofit-detail-header {
    margin-bottom: var(--spacing-xl);
}

.retrofit-detail-title {
    font-size: var(--font-size-3xl);
    font-weight: 700;
    color: var(--gray-800);
}

.retrofit-detail-image {
    max-width: 100%;
    max-height: 400px;
    object-fit: contain;
    border-radius: var(--radius-lg);
    margin-bottom: var(--spacing-xl);
}

.retrofit-detail-section {
    background: var(--white);
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-lg);
    padding: var(--spacing-xl);
    margin-bottom: var(--spacing-xl);
}

.retrofit-detail-section h3 {
    color: var(--primary);
    margin-bottom: var(--spacing-md);
    font-size: var(--font-size-xl);
}

.retrofit-parts-table {
    width: 100%;
    border-collapse: collapse;
}

.retrofit-parts-table th,
.retrofit-parts-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    text-align: left;
    border-bottom: 1px solid var(--gray-200);
}

.retrofit-parts-table th {
    background: var(--gray-100);
    font-weight: 600;
    color: var(--gray-600);
}

/* ================================================================
   EDIT RETROFIT KIT
   ================================================================ */

.edit-retrofit-container {
    padding: var(--spacing-xl);
    /* Clearance so the last row is not hidden behind the fixed footer. */
    padding-bottom: 72px;
}

.edit-retrofit-table {
    width: 100%;
    border-collapse: collapse;
}

.edit-retrofit-table th,
.edit-retrofit-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    text-align: left;
    border-bottom: 1px solid var(--gray-200);
    vertical-align: middle;
}

.edit-retrofit-table th {
    background: var(--primary);
    color: var(--white);
    font-weight: 600;
}

.edit-retrofit-table tr:hover {
    background: var(--gray-100);
}

/* ================================================================
   MAINTENANCE SETTINGS
   ================================================================ */

.maintenance-settings-container {
    padding: var(--spacing-lg);
    overflow-y: auto;
}

.maintenance-settings-table {
    width: 100%;
    border-collapse: collapse;
}

.maintenance-settings-table th,
.maintenance-settings-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    text-align: left;
    border-bottom: 1px solid var(--gray-200);
    vertical-align: middle;
}

.maintenance-settings-table th {
    background: var(--primary);
    color: var(--white);
    font-weight: 600;
}

.maintenance-settings-table tr:hover {
    background: var(--gray-100);
}

/* ================================================================
   BTN-SM COMBO FIX
   ================================================================ */

.btn-danger.btn-sm {
    padding: var(--spacing-xs) var(--spacing-md) !important;
    font-size: var(--font-size-sm) !important;
}

.btn-outline.btn-sm {
    padding: var(--spacing-xs) var(--spacing-md) !important;
    font-size: var(--font-size-sm) !important;
}

.btn-success.btn-sm {
    padding: var(--spacing-xs) var(--spacing-md) !important;
    font-size: var(--font-size-sm) !important;
}

/* ================================================================
   MAINTENANCE / RETROFIT EDIT DIALOG WIDGETS
   ================================================================ */

/* Form row helper — every label + input pair gets stacked vertically */
.form-row {
    display: block !important;
    margin-bottom: 12px !important;
}

.form-row > .form-label {
    display: block !important;
    font-weight: 600 !important;
    color: var(--gray-700) !important;
    font-size: var(--font-size-sm) !important;
    margin-bottom: 4px !important;
}

.form-row > input.edit-input,
.form-row > textarea.edit-textarea {
    display: block !important;
    width: 100% !important;
    box-sizing: border-box !important;
}

/* Section title — block heading inside dialog */
.dialog-section-title {
    display: block !important;
    font-weight: 700 !important;
    color: var(--primary) !important;
    margin-top: 16px !important;
    margin-bottom: 8px !important;
    border-bottom: 2px solid var(--gray-200) !important;
    padding-bottom: 4px !important;
    font-size: var(--font-size-base) !important;
}

/* Make sure the dialog body itself can scroll. Wt's dialog DOM puts the
   contents container under .body — so we cover both the new and old
   class names just in case. */
.edit-dialog,
.Wt-dialog.edit-dialog,
div.Wt-dialog.edit-dialog {
    max-width: 90vw !important;
    max-height: 90vh !important;
}

.edit-dialog .body,
.edit-dialog .Wt-dialog-body,
.edit-dialog > .body,
.Wt-dialog.edit-dialog > .body,
.Wt-dialog.edit-dialog .Wt-dialog-content,
.Wt-dialog.edit-dialog .body > div {
    max-height: 75vh !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
}

/* Part / assembly editor dialogs fill the viewport, capped on wide monitors so
   forms don't stretch absurdly. Width is set inline (90vw); the cap wins on big
   screens, and on narrow/portrait screens the 90vw drives the size. */
.edit-dialog-lg,
.Wt-dialog.edit-dialog-lg,
div.Wt-dialog.edit-dialog-lg {
    max-width: 1250px !important;
    max-height: 92vh !important;
}
.edit-dialog-lg .body,
.edit-dialog-lg .Wt-dialog-body,
.edit-dialog-lg > .body,
.Wt-dialog.edit-dialog-lg > .body,
.Wt-dialog.edit-dialog-lg .Wt-dialog-content,
.Wt-dialog.edit-dialog-lg .body > div {
    max-height: 84vh !important;
}

/* Titlebar, tabs and footer stop short of the right edge on a wide screen:
   the root takes the inline 90vw (capped at 1250px) while the layout boxes
   keep hugging their content. Same fix the mobile contract applies when the
   media query narrows the root, but the gap appears on desktop too. Scoped to
   -lg — the small .edit-dialog confirms hug their content deliberately. */
.edit-dialog-lg > .dialog-layout,
.edit-dialog-lg > .Wt-dialog-contents,
.edit-dialog-lg > .contents,
.edit-dialog-lg .body,
.edit-dialog-lg .Wt-dialog-body {
    width: 100% !important;
    box-sizing: border-box !important;
}

/* CustomTabs inside the part/assembly editor: the tab body is a fixed-height
   Wt layout item that clips instead of scrolling, so an add-row "+" below a
   long BOM list falls off-screen with no usable scrollbar. Give the tab stack
   its own internal scroll (the .ctabs-bar stays pinned). Scoped to
   .edit-dialog so the settings and name-slot CustomTabs are unaffected. */
.edit-dialog .ctabs {
    display: flex !important;
    flex-direction: column !important;
    min-height: 0 !important;
}
/* The bar's overflow-y:hidden drops its automatic min-height to 0, so a tall
   tab page (Details) would shrink it and clip the tab labels. */
.edit-dialog .ctabs-bar {
    flex: 0 0 auto !important;
}
.edit-dialog .ctabs-stack {
    flex: 1 1 auto !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    min-height: 0 !important;
}

/* Part links popup: exactly one scroll container, the tab stack. The generic
   `.edit-dialog .body > div` rule turns the CustomTabs root into a second
   75vh scroll box; with both scrolling, the sticky tab bar rides up out of
   view as soon as a tab holds more than a screenful. */
.part-detail-dialog .body > div,
.part-detail-dialog .Wt-dialog-body > div,
.part-detail-dialog .Wt-dialog-content > div {
    max-height: none !important;
    overflow: visible !important;
}

.part-detail-dialog .ctabs {
    display: flex !important;
    flex-direction: column !important;
    max-height: 70vh !important;
    min-height: 0 !important;
}

.part-detail-dialog .ctabs-stack {
    flex: 1 1 auto !important;
    overflow-y: auto !important;
    min-height: 0 !important;
}

/* Hours / chip picker container */
.hours-picker-container {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 4px !important;
    padding: 8px !important;
    border: 1px solid var(--gray-300) !important;
    border-radius: var(--radius-md) !important;
    background: var(--white) !important;
    margin-bottom: 12px !important;
}

/* Override Wt's default button styling on chips */
button.hour-chip,
.hour-chip,
.hours-picker-container button {
    padding: 6px 14px !important;
    border: 1px solid var(--gray-400) !important;
    border-radius: 20px !important;
    background: var(--gray-100) !important;
    color: var(--gray-800) !important;
    font-size: var(--font-size-sm) !important;
    font-weight: 500 !important;
    cursor: pointer !important;
    margin: 0 !important;
    min-width: 56px !important;
    height: auto !important;
    line-height: 1.2 !important;
    text-align: center !important;
    text-decoration: none !important;
    box-shadow: none !important;
    transition: all 0.12s !important;
}

button.hour-chip:hover,
.hour-chip:hover {
    border-color: var(--primary) !important;
    color: var(--primary) !important;
    background: var(--primary-light, #e8f5e9) !important;
}

button.hour-chip-active,
.hour-chip-active,
.hour-chip-active:hover {
    background: var(--primary) !important;
    color: var(--white) !important;
    border-color: var(--primary) !important;
    font-weight: 600 !important;
}

/* ── Engine tab set (custom horizontal tabs with stacked content) ── */
.engine-tabset {
    display: flex;
    flex-direction: column;
    width: 100%;
}

.engine-tab-bar {
    display: flex !important;
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    gap: 4px !important;
    padding: 6px 6px 0 6px !important;
    background: #f7f9f8 !important;
    border-bottom: 2px solid var(--primary) !important;
    -webkit-overflow-scrolling: touch !important;
}

button.engine-tab,
.engine-tab,
.engine-tab-bar > button {
    padding: 8px 14px !important;
    background: transparent !important;
    border: 1px solid transparent !important;
    border-radius: 8px 8px 0 0 !important;
    color: var(--gray-700) !important;
    font-size: var(--font-size-sm) !important;
    font-weight: 500 !important;
    cursor: pointer !important;
    white-space: nowrap !important;
    flex: 0 0 auto !important;
    margin: 0 !important;
    box-shadow: none !important;
    text-decoration: none !important;
    line-height: 1.4 !important;
}

button.engine-tab:hover,
.engine-tab-bar > button:hover {
    background: var(--primary-light, #e8f5e9) !important;
    color: var(--primary) !important;
}

button.engine-tab-active,
.engine-tab-active,
.engine-tab-active:hover {
    background: var(--white) !important;
    color: var(--primary) !important;
    border-color: var(--gray-300) !important;
    border-bottom-color: var(--white) !important;
    font-weight: 700 !important;
    margin-bottom: -2px !important;
}

.engine-tab-stack {
    flex: 1 1 auto !important;
    padding: 12px !important;
    background: var(--white) !important;
    border: 1px solid var(--gray-300) !important;
    border-top: none !important;
    border-radius: 0 0 6px 6px !important;
    overflow: visible !important;
    min-height: 320px !important;
    height: auto !important;
    display: block !important;
}

.engine-tab-stack > div {
    height: auto !important;
    min-height: 0 !important;
    display: block;
}

.engine-tab-stack > div[style*="display: none"] {
    display: none !important;
}

/* ── Multi-language text cells (EN / DE / FR rows in tables) ────── */
.multi-lang {
    display: flex !important;
    flex-direction: column !important;
    gap: 2px !important;
    /* Keep the cell at a readable width so words don't get squeezed
       letter-by-letter when the table column auto-sizes too narrow. */
    min-width: 220px !important;
    max-width: 360px !important;
}

.lang-row {
    display: flex !important;
    align-items: flex-start !important;
    gap: 6px !important;
    line-height: 1.35 !important;
    min-width: 0 !important;
}

.lang-tag {
    display: inline-block !important;
    flex: 0 0 auto !important;
    min-width: 26px !important;
    padding: 1px 5px !important;
    background: var(--gray-200) !important;
    border-radius: 3px !important;
    font-size: calc(10px * var(--font-scale)) !important;
    font-weight: 700 !important;
    color: var(--gray-600) !important;
    text-align: center !important;
    line-height: 16px !important;
    align-self: flex-start;
}

.lang-text {
    flex: 1 1 auto !important;
    font-size: var(--font-size-sm) !important;
    color: var(--gray-800) !important;
    /* Keep whole words together. break-word was the culprit: under a
       narrow column it was breaking each word into one letter per line. */
    word-break: keep-all !important;
    overflow-wrap: break-word !important;
    white-space: normal !important;
}

/* ── Shared options summary box (inside same-options group panel) ── */
.shared-options-box {
    display: block;
    padding: 8px 10px;
    margin-bottom: 10px;
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-md);
    background: var(--gray-100);
}

.shared-options-row {
    display: flex !important;
    flex-wrap: wrap !important;
    align-items: center !important;
    gap: 6px !important;
    padding: 4px 0 !important;
}

.shared-options-row + .shared-options-row {
    border-top: 1px dashed var(--gray-200);
}

.shared-options-label {
    display: inline-block !important;
    min-width: 150px !important;
    font-weight: 600 !important;
    color: var(--gray-700) !important;
    font-size: var(--font-size-sm) !important;
}

.shared-options-empty {
    display: block;
    padding: 4px 0;
    color: var(--gray-500);
    font-style: italic;
    font-size: var(--font-size-sm);
}

/* ── Collapsible panel (replacement for WPanel) ──────────────────── */
.collapsible-panel {
    border: 1px solid var(--gray-200);
    border-radius: 6px;
    margin-bottom: 8px;
    background: var(--white);
    overflow: hidden;
}

.collapsible-panel-header {
    display: flex !important;
    align-items: center !important;
    padding: 10px 14px !important;
    cursor: pointer !important;
    user-select: none !important;
    background: var(--gray-100) !important;
    transition: background 0.12s !important;
}

.collapsible-panel-header:hover {
    background: #e9ecef !important;
}

.collapsible-panel-header .chevron {
    display: inline-block;
    margin-right: 10px;
    color: var(--primary);
    font-size: calc(12px * var(--font-scale));
    transition: transform 0.15s;
}

.collapsible-panel-open > .collapsible-panel-header .chevron {
    transform: rotate(90deg);
}

.collapsible-panel-title {
    flex: 1 !important;
    font-weight: 600 !important;
    color: var(--gray-800) !important;
}

.collapsible-panel-body {
    padding: 12px;
    border-top: 1px solid var(--gray-200);
    background: var(--white);
}

.part-list-editor {
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-md);
    padding: 8px;
    background: var(--gray-100);
}

/* Compact chip-style list — items wrap horizontally instead of stacking
   one row per line, so a kit with 30 parts still fits in ~6 rows. */
.part-list-rows {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 6px !important;
    margin-bottom: 8px !important;
    max-height: 200px !important;
    overflow-y: auto !important;
    padding: 4px !important;
    background: var(--white) !important;
    border: 1px solid var(--gray-200) !important;
    border-radius: 4px !important;
}

.part-list-row {
    display: inline-flex !important;
    align-items: center !important;
    gap: 6px !important;
    padding: 4px 4px 4px 10px !important;
    background: var(--white) !important;
    border: 1px solid var(--gray-300) !important;
    border-radius: 16px !important;
    font-size: var(--font-size-sm) !important;
}

.part-list-row .pn {
    font-weight: 500 !important;
    color: var(--gray-800) !important;
}

.part-list-row .qty {
    color: var(--primary) !important;
    font-weight: 600 !important;
    background: var(--primary-light, #e8f5e9) !important;
    padding: 1px 6px !important;
    border-radius: 10px !important;
    font-size: var(--font-size-xs, 11px) !important;
}

.part-list-row .btn-remove {
    background: transparent !important;
    border: none !important;
    color: var(--gray-500) !important;
    cursor: pointer !important;
    padding: 0 4px !important;
    font-size: var(--font-size-base) !important;
    min-width: auto !important;
    line-height: 1 !important;
}

.part-list-row .btn-remove:hover {
    color: #dc3545 !important;
}

.part-list-add-row {
    display: flex;
    gap: 6px;
    align-items: center;
}

.part-list-add-row .pn-input {
    flex: 1;
}

.part-list-add-row .qty-input {
    width: 80px;
}

.part-list-empty {
    padding: 8px;
    color: var(--gray-500);
    font-style: italic;
    text-align: center;
    font-size: var(--font-size-sm);
}

.dialog-section-title {
    font-weight: 600;
    color: var(--primary);
    margin-top: 8px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--gray-200);
    padding-bottom: 4px;
}

/* =========================================================
   Statistics page (StatsPage, StatsUi widgets)
   ========================================================= */

/* ---- Statistics page ---- */
.stats-page { padding: 20px; width: 100%; box-sizing: border-box; }
.stats-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin-bottom: 14px; font-size: var(--font-size-sm); }
.stats-field { display: flex; align-items: center; gap: 6px; }
.stats-field-label { color: var(--gray-600); font-size: var(--font-size-sm); white-space: nowrap; }
.stats-field select { min-width: 140px; max-width: 240px; }
.stats-reset-btn { margin-left: auto; }
.stats-content { display: flex; flex-direction: column; gap: 14px; }

.stats-usercard { border: 1px solid var(--gray-200); border-left: 4px solid var(--primary); border-radius: 6px; background: #fff; padding: 12px 16px; }
.stats-usercard-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.stats-usercard-name { font-size: var(--font-size-lg); font-weight: 700; color: var(--gray-900, var(--gray-800)); }
.stats-usercard-clear { border: 1px solid var(--gray-300); background: #fff; color: var(--gray-700); border-radius: 50%; width: 26px; height: 26px; padding: 0; line-height: 1; font-size: var(--font-size-base); cursor: pointer; }
.stats-usercard-clear:hover { background: var(--gray-100); color: var(--danger); border-color: var(--danger); }
.stats-usercard-meta { display: flex; flex-wrap: wrap; gap: 8px 28px; }
.stats-usercard-label { color: var(--gray-600); font-size: var(--font-size-xs); }
.stats-usercard-value { color: var(--gray-800); font-size: var(--font-size-base); font-weight: 600; }

.statsui-kpi-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 12px; }
.statsui-kpi { border: 1px solid var(--gray-200); border-radius: 6px; background: #fff; padding: 10px 14px; }
.statsui-kpi-value { display: block; font-size: var(--font-size-xl); font-weight: 700; color: var(--gray-800); line-height: 1.2; }
.statsui-kpi-label { display: block; color: var(--gray-600); font-size: var(--font-size-xs); margin-top: 2px; text-transform: uppercase; letter-spacing: .04em; }
.statsui-kpi-sub { display: block; color: var(--gray-500); font-size: var(--font-size-xs); margin-top: 2px; }

.statsui-panel { border: 1px solid var(--gray-200); border-radius: 6px; background: #fff; min-width: 0; }
.statsui-panel-title { display: block; padding: 10px 14px; border-bottom: 1px solid var(--gray-200); font-size: var(--font-size-sm); font-weight: 700; color: var(--gray-700); text-transform: uppercase; letter-spacing: .04em; }
.statsui-panel-body { padding: 12px 14px; }
.stats-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
@media (max-width: 900px) { .stats-grid { grid-template-columns: 1fr; } .stats-reset-btn { margin-left: 0; } }

.statsui-bar-list { display: flex; flex-direction: column; gap: 4px; }
.statsui-bar-row { display: grid; grid-template-columns: 22px minmax(0, 1.4fr) minmax(40px, 1fr) auto; align-items: center; gap: 10px; padding: 5px 6px; border-radius: 4px; }
.statsui-bar-row-click:hover { background: var(--gray-100); }
.statsui-bar-rank { color: var(--gray-500); font-size: var(--font-size-xs); text-align: right; }
.statsui-bar-label { min-width: 0; }
.statsui-bar-name { display: block; font-size: var(--font-size-sm); font-weight: 600; color: var(--gray-800); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.statsui-bar-sub { display: block; font-size: var(--font-size-xs); color: var(--gray-600); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.statsui-bar-track { height: 8px; background: var(--gray-200); border-radius: 4px; overflow: hidden; }
.statsui-bar-fill { height: 100%; background: var(--primary); border-radius: 4px; }
.statsui-bar-value { font-size: var(--font-size-sm); font-weight: 700; color: var(--gray-800); text-align: right; font-variant-numeric: tabular-nums; }
.statsui-empty { color: var(--gray-600); font-size: var(--font-size-sm); padding: 10px 0; }

.statsui-chart { position: relative; display: flex; align-items: flex-end; gap: 2px; height: 160px; border-bottom: 1px solid var(--gray-300); }
.statsui-col { position: relative; flex: 1 1 0; min-width: 2px; height: 100%; display: flex; align-items: flex-end; }
.statsui-col:hover { background: var(--gray-100); }
.statsui-col-bar { width: 100%; background: var(--primary); opacity: .85; border-radius: 2px 2px 0 0; }
.statsui-col-mark { position: absolute; left: 50%; width: 6px; height: 6px; margin: 0 0 -3px -3px; border-radius: 50%; background: var(--info); border: 1px solid #fff; }
.statsui-chart-axis { display: flex; justify-content: space-between; margin-top: 4px; color: var(--gray-600); font-size: var(--font-size-xs); }
.statsui-legend { display: flex; gap: 16px; margin-top: 8px; font-size: var(--font-size-xs); color: var(--gray-700); }
.statsui-legend-v1::before, .statsui-legend-v2::before { content: ""; display: inline-block; width: 10px; height: 10px; margin-right: 6px; vertical-align: middle; }
.statsui-legend-v1::before { background: var(--primary); border-radius: 2px; }
.statsui-legend-v2::before { background: var(--info); border-radius: 50%; }
@media (max-width:600px){ .statsui-bar-row{grid-template-columns:18px minmax(0,1fr) auto;} .statsui-bar-track{display:none;} }

/* Table/empty rules still used by the performance page. */
.stats-empty {
    color: var(--gray-500);
    font-style: italic;
    padding: 16px;
    display: block;
}

.stats-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
}

.stats-table th,
.stats-table td {
    padding: 8px 12px;
    border-bottom: 1px solid var(--gray-100);
    text-align: left;
}

.stats-table thead th,
.stats-table tr:first-child td {
    background: var(--gray-100);
    font-weight: 600;
    color: var(--gray-700);
    border-bottom: 2px solid var(--gray-200);
    /* Header stays put while the body scrolls. */
    position: sticky;
    top: 0;
    z-index: 1;
}

.stats-table tbody tr:hover {
    background: var(--gray-100);
}

/* Shared by the performance tables. */
@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
    .stats-table {
        min-width: 480px !important;
    }

    .stats-table th,
    .stats-table td {
        padding: 6px 8px !important;
        font-size: var(--font-size-xs) !important;
    }
}

/* =========================================================
   Audit Log page
   ========================================================= */

/* Audit log page */
.audit-log-page .audit-toolbar { display:grid; grid-template-columns:repeat(auto-fill, minmax(160px, 1fr)); gap:12px 14px; align-items:end; margin-bottom:12px; }
.audit-log-page .audit-filter-card { padding:14px; border:1px solid var(--gray-200); border-radius:6px; background:#fff; }
.audit-log-page .audit-field { display:flex; flex-direction:column; gap:4px; min-width:0; }
.audit-log-page .audit-field-label { font-size:11px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; color:var(--gray-600); }
.audit-log-page .audit-input { width:100%; min-width:0; max-width:100%; }
.audit-input { box-sizing:border-box; height:32px; padding:4px 8px; border:1px solid var(--gray-300); border-radius:4px; background:#fff; font-size:var(--font-size-sm); }
.audit-input:focus { outline:none; border-color:var(--primary); }
.audit-input:disabled { background:var(--gray-100); color:var(--gray-500); cursor:not-allowed; }
.audit-log-page .audit-field-off .audit-field-label { opacity:.5; }
.audit-log-page .audit-actions { grid-column:1 / -1; display:flex; flex-wrap:wrap; gap:8px; justify-content:flex-end; padding-top:10px; border-top:1px solid var(--gray-200); }
.audit-log-page .audit-info { display:flex; justify-content:space-between; align-items:center; gap:8px; padding:8px 14px; background:var(--gray-100); border:1px solid var(--gray-200); border-bottom:0; border-radius:6px 6px 0 0; font-size:var(--font-size-sm); color:var(--gray-700); }
.audit-log-page .audit-info b { color:var(--gray-800); font-size:var(--font-size-base); }
.audit-log-page .audit-range { color:var(--gray-600); font-variant-numeric:tabular-nums; }
.audit-log-page .audit-table-wrap { overflow:auto; max-width:100%; max-height:calc(100vh - 260px); min-height:120px; border:1px solid var(--gray-200); border-radius:0 0 6px 6px; background:#fff; -webkit-overflow-scrolling:touch; }
.audit-log-page .audit-table { width:100%; border-collapse:separate; border-spacing:0; }
.audit-log-page .audit-table th { position:sticky; top:0; z-index:1; background:var(--gray-100); padding:8px 10px; text-align:left; white-space:nowrap; font-size:11px; font-weight:700; letter-spacing:.04em; text-transform:uppercase; color:var(--gray-600); border-bottom:1px solid var(--gray-200); }
.audit-log-page .audit-table td { padding:8px 10px; text-align:left; vertical-align:top; border-bottom:1px solid var(--gray-100); font-size:var(--font-size-sm); }
.audit-log-page .audit-table td.c-change { min-width:220px; }
.audit-log-page .audit-row { cursor:pointer; }
.audit-log-page .audit-row:nth-child(even) td { background:#fafbfc; }
.audit-log-page .audit-row:hover td { background:rgba(13,110,253,.07); }
.audit-log-page .audit-cell-click { cursor:pointer; }
.audit-log-page .audit-day, .audit-log-page .audit-clock, .audit-log-page .audit-user, .audit-log-page .audit-role { display:block; }
.audit-log-page .audit-day { font-variant-numeric:tabular-nums; white-space:nowrap; color:var(--gray-800); }
.audit-log-page .audit-clock { font-size:11px; color:var(--gray-500); font-variant-numeric:tabular-nums; }
.audit-log-page .audit-user { font-weight:700; color:var(--gray-800); }
.audit-log-page .audit-role { font-size:11px; color:var(--gray-500); }
.audit-badge { display:inline-block; padding:2px 9px; border-radius:999px; font-size:11px; font-weight:700; letter-spacing:.03em; text-transform:uppercase; line-height:1.5; background:var(--gray-200); color:var(--gray-700); }
.audit-badge-create { background:#d1f0dc; color:#146c2e; }
.audit-badge-update { background:#d6e6fd; color:#0b4fa8; }
.audit-badge-delete { background:#fbd9dc; color:#a11d2b; }
.audit-badge-login, .audit-badge-logout { background:var(--gray-200); color:var(--gray-700); }
.audit-badge-import { background:#e6dcf7; color:#5b2d9e; }
.audit-badge-export { background:#d0efee; color:#0b6b66; }
.audit-log-page .audit-chip { display:inline-block; padding:1px 8px; border-radius:4px; background:var(--gray-100); border:1px solid var(--gray-200); font-size:11px; color:var(--gray-700); }
.audit-log-page .audit-mono, .audit-log-page .audit-ip, .audit-detail-dialog .audit-detail-entity { display:block; font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:12px; }
.audit-log-page .audit-mono { margin-top:3px; color:var(--gray-800); word-break:break-all; }
.audit-log-page .audit-ip { color:var(--gray-500); white-space:nowrap; }
.audit-log-page .audit-field-name { display:block; font-size:11px; color:var(--gray-500); margin-bottom:2px; }
.audit-log-page .audit-change { display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 6px; }
.audit-log-page .audit-old, .audit-log-page .audit-new { display:inline-block; max-width:100%; padding:1px 6px; border-radius:4px; font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:12px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; vertical-align:bottom; }
.audit-log-page .audit-old { background:rgba(220,53,69,.09); color:var(--gray-600); text-decoration:line-through; text-decoration-color:rgba(220,53,69,.55); }
.audit-log-page .audit-new { background:rgba(25,135,84,.11); color:#146c2e; }
.audit-log-page .audit-arrow { color:var(--gray-500); }
.audit-log-page .audit-empty { display:flex; flex-direction:column; align-items:center; gap:8px; padding:36px 12px; color:var(--gray-500); text-align:center; }
.audit-log-page .audit-empty-icon .app-icon { width:36px; height:36px; opacity:.45; }
.audit-log-page .audit-pager { display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:8px; margin:14px 0; }
.audit-log-page .audit-pager button { border-radius:999px; min-width:36px; padding:4px 14px; }
.audit-log-page .audit-pager button:disabled { opacity:.45; cursor:not-allowed; }
.audit-log-page .audit-pager-text { min-width:110px; text-align:center; font-size:var(--font-size-sm); color:var(--gray-700); font-variant-numeric:tabular-nums; }
@media (max-width: 900px) {
  .audit-log-page .audit-table .c-ip { display:none; }
}
@media (max-width: 640px) {
  .audit-log-page .audit-toolbar { grid-template-columns:1fr 1fr; }
  .audit-log-page .audit-actions .btn-primary, .audit-log-page .audit-actions .btn-secondary { flex:1 1 auto; }
  .audit-log-page .audit-table-wrap { max-height:none; border:0; background:transparent; }
  .audit-log-page .audit-table, .audit-log-page .audit-table tbody, .audit-log-page .audit-table tr, .audit-log-page .audit-table td { display:block; width:100%; box-sizing:border-box; }
  .audit-log-page .audit-table tr:first-child { display:none; }
  .audit-log-page .audit-row { margin-bottom:10px; border:1px solid var(--gray-200); border-radius:6px; background:#fff; overflow:hidden; }
  .audit-log-page .audit-row td, .audit-log-page .audit-row:nth-child(even) td { background:#fff; border-bottom:1px solid var(--gray-100); display:flex; gap:10px; align-items:flex-start; flex-wrap:wrap; }
  .audit-log-page .audit-row td::before { content:attr(data-label); flex:0 0 76px; font-size:11px; font-weight:700; letter-spacing:.04em; text-transform:uppercase; color:var(--gray-500); }
  .audit-log-page .audit-row td.c-ip { display:flex; }
  .audit-log-page .audit-row td > * { min-width:0; }
}
.audit-detail-dialog { width:720px; max-width:96vw; }
.audit-detail-dialog .audit-detail-body { width:100%; }
.audit-detail-dialog .audit-detail-head { display:flex; flex-wrap:wrap; align-items:center; gap:10px; padding-bottom:10px; margin-bottom:10px; border-bottom:1px solid var(--gray-200); }
.audit-detail-dialog .audit-detail-entity { color:var(--gray-800); word-break:break-all; }
.audit-detail-dialog .audit-detail-grid { display:grid; grid-template-columns:max-content 1fr; gap:6px 16px; margin-bottom:12px; padding:10px 12px; background:var(--gray-100); border:1px solid var(--gray-200); border-radius:6px; }
.audit-detail-dialog .audit-detail-label { font-size:11px; font-weight:700; letter-spacing:.04em; text-transform:uppercase; color:var(--gray-600); display:block; }
.audit-detail-dialog .audit-detail-field { word-break:break-word; }
.audit-detail-dialog .audit-detail-diff { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.audit-detail-dialog .audit-detail-box { min-width:0; }
.audit-detail-dialog .audit-detail-value { white-space:pre-wrap; word-break:break-word; max-height:220px; overflow:auto; border:1px solid var(--gray-200); border-left-width:4px; border-radius:4px; padding:6px 8px; margin:4px 0 6px; font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:12px; background:#fff; }
.audit-detail-dialog .audit-box-old .audit-detail-value { border-left-color:var(--danger); background:rgba(220,53,69,.05); }
.audit-detail-dialog .audit-box-new .audit-detail-value { border-left-color:#198754; background:rgba(25,135,84,.06); }
.Wt-dialog.audit-detail-dialog > .dialog-layout,
.Wt-dialog.audit-detail-dialog .titlebar,
.Wt-dialog.audit-detail-dialog .body,
.Wt-dialog.audit-detail-dialog .footer { width:100% !important; box-sizing:border-box !important; }
/* Dialog footer: plain bar, not the page-footer green. */
.Wt-dialog.audit-detail-dialog .footer { background:transparent !important; color:inherit !important; margin:0 !important; border-radius:0 !important; border-top:1px solid var(--gray-200); padding:10px 16px !important; text-align:right !important; }
.audit-detail-dialog .audit-detail-value { min-height:32px; box-sizing:border-box; }
.audit-detail-dialog .audit-detail-value-empty { color:var(--gray-500); }
/* Filter card and results stay within the tab width; only the table wrap scrolls. */
.settings-logs-content, .settings-logs-content .ctabs-stack, .settings-logs-content .ctabs-stack > div { min-width:0; max-width:100%; box-sizing:border-box; }
.audit-log-page { width:100%; max-width:100%; min-width:0; box-sizing:border-box; overflow-x:hidden; }
.audit-log-page .audit-filter-card { box-sizing:border-box; width:100%; max-width:100%; grid-template-columns:repeat(auto-fill, minmax(min(160px, 100%), 1fr)); }
.audit-log-page .audit-field > *, .audit-log-page .audit-field input, .audit-log-page .audit-field select { min-width:0; max-width:100%; box-sizing:border-box; }
.audit-log-page .audit-info, .audit-log-page .audit-table-wrap { box-sizing:border-box; max-width:100%; }

/* =========================================================
   Performance metrics page
   ========================================================= */

.performance-page {
    padding: 16px;
    width: 100%;
    box-sizing: border-box;
}

.performance-toolbar {
    margin-bottom: 12px;
    font-size: var(--font-size-sm);
}

.performance-toolbar > div {
    align-items: center;
}

.performance-live-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 12px;
    margin-bottom: 14px;
}

.performance-live-card {
    border: 1px solid var(--gray-200);
    border-radius: 6px;
    background: #fff;
    padding: 10px 12px;
    min-height: 150px;
    overflow: hidden;
}

.performance-live-card h3 {
    margin: 0 0 10px;
    color: var(--gray-800);
    font-size: var(--font-size-md);
}

.performance-live-metric {
    display: grid;
    grid-template-columns: minmax(88px, 1fr) auto;
    gap: 8px;
    align-items: baseline;
    padding: 3px 0;
    font-size: var(--font-size-sm);
}

.performance-live-metric-label {
    color: var(--gray-600);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.performance-live-metric-value {
    color: var(--gray-900);
    font-weight: 700;
    text-align: right;
}

.performance-stack {
    display: flex;
    height: 14px;
    border-radius: 999px;
    overflow: hidden;
    background: var(--gray-100);
    margin-bottom: 10px;
}

.performance-stack-segment {
    height: 100%;
}

.performance-detail-caption {
    display: block;
    padding: 8px 12px;
    color: var(--gray-600);
    font-size: var(--font-size-sm);
}

.performance-table {
    border-top: 0;
}

/* .performance-section already has overflow:auto (unconditional, above),
   but a width:100% table never triggers it. min-width sized to the widest
   of the 3 performance tables (up to 9 columns) so it scrolls instead of
   crushing; padding/font-size come from the shared .stats-table mobile
   rule above and win the cascade there since this comes later in file. */
@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
    .performance-section {
        -webkit-overflow-scrolling: touch;
    }

    .performance-table {
        min-width: 900px !important;
    }
}

.performance-band-fast { background: #198754; }
.performance-band-ok   { background: #0d6efd; }
.performance-band-warn { background: #fd7e14; }
.performance-band-slow { background: #dc3545; }

.performance-toolbar-flex { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.performance-kpi-strip { margin-bottom: 14px; }   /* strip is also .statsui-kpi-strip */
.performance-results > * { margin-bottom: 14px; }
.performance-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
  .performance-toolbar-flex .audit-input { flex: 1 1 140px; min-width: 0; }
  .performance-table { min-width: 900px !important; }
}
.performance-lat-fast { color: #2e7d32; }
.performance-lat-ok   { color: #5f6b00; }
.performance-lat-warn { color: #e65100; font-weight: 600; }
.performance-lat-slow { color: #c62828; font-weight: 700; }
.performance-stage-track { width: 100%; min-width: 220px; height: 14px; background: var(--gray-100); border-radius: 999px; overflow: hidden; }
.performance-stage-bar { display: flex; height: 100%; overflow: hidden; border-radius: 999px; }
.performance-stage-seg { height: 100%; flex: 0 0 auto; }
.performance-stage-file-read      { background: #1565c0; }
.performance-stage-image-ref      { background: #2e7d32; }
.performance-stage-image-fallback { background: #f9a825; }
.performance-stage-bom-maps       { background: #6a1b9a; }
.performance-stage-transform      { background: #e65100; }
.performance-stage-hotspot        { background: #00838f; }
.performance-stage-other          { background: #9e9e9e; }
.performance-stage-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 10px; font-size: var(--font-size-xs); color: var(--gray-700); }
.performance-stage-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.performance-stage-dot { width: 9px; height: 9px; border-radius: 999px; display: inline-block; flex-shrink: 0; }

/* =========================================================
   Error pages (404 etc.)
   ========================================================= */

.error-page {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: calc(100vh - 200px);
    padding: 40px 20px;
    box-sizing: border-box;
}

.error-card {
    text-align: center;
    max-width: 480px;
    padding: 48px 32px;
    background: #fff;
    border: 1px solid var(--gray-200);
    border-radius: 12px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.06);
}

.error-logo {
    max-width: 180px;
    height: auto;
    margin-bottom: 24px;
    opacity: 0.9;
}

.error-code {
    display: block;
    font-size: calc(96px * var(--font-scale));
    font-weight: 800;
    color: var(--primary);
    line-height: 1;
    letter-spacing: -2px;
    margin-bottom: 8px;
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.error-headline {
    display: block;
    font-size: calc(22px * var(--font-scale));
    font-weight: 600;
    color: var(--gray-700);
    margin-bottom: 12px;
}

.error-sub {
    display: block;
    color: var(--gray-600);
    font-size: calc(14px * var(--font-scale));
    margin-bottom: 28px;
    word-break: break-word;
}

.error-sub code {
    background: var(--gray-100);
    padding: 2px 6px;
    border-radius: 4px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    color: var(--primary-dark);
    font-size: 0.92em;
}

.error-home-btn {
    padding: 10px 24px;
    font-size: calc(15px * var(--font-scale));
    font-weight: 600;
}

/* Compact on small screens */
@media (max-width: 600px) {
    .error-card  { padding: 32px 20px; }
    .error-logo  { max-width: 140px; }
    .error-code  { font-size: calc(72px * var(--font-scale)); }
    .error-headline { font-size: calc(18px * var(--font-scale)); }
}

/* =========================================================
   Favorites — star widget + page + homepage card
   ========================================================= */

.favorite-star {
    cursor: pointer;
    font-size: 1.4em;
    line-height: 1;
    margin-left: 6px;
    vertical-align: middle;
    user-select: none;
    transition: transform 0.1s ease, color 0.15s ease;
}

.favorite-star:hover {
    transform: scale(1.15);
}

.favorite-star.off {
    color: var(--gray-500);
}

.favorite-star.on {
    color: #f5b301;
    text-shadow: 0 0 2px rgba(245, 179, 1, 0.4);
}

.favorites-page {
    padding: 20px;
    width: 100%;
    box-sizing: border-box;
}

.favorites-page > h2 {
    margin-top: 0;
    margin-bottom: 16px;
}

.favorites-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
}

.favorites-table th,
.favorites-table td {
    padding: 8px 12px;
    border-bottom: 1px solid var(--gray-100);
    text-align: left;
    vertical-align: middle;
}

.favorites-table thead th,
.favorites-table tr:first-child td {
    background: var(--gray-100);
    font-weight: 600;
    color: var(--gray-700);
    border-bottom: 2px solid var(--gray-200);
}

.favorites-table tbody tr:hover {
    background: var(--gray-100);
}

/* No dedicated scroll wrapper here: FavoritesPage sets overflow:auto on the
   whole page (favoritespage.cpp), which already scrolls horizontally. Give
   the 7-column table a min-width so it scrolls instead of crushing, and
   trim padding/font a bit to fit more before that point. */
@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
    .favorites-table {
        min-width: 700px !important;
    }

    .favorites-table th,
    .favorites-table td {
        padding: 6px 8px !important;
        font-size: var(--font-size-xs) !important;
    }
}

/* Homepage "My Favorites (N)" mini-card */
.favorites-card {
    display: inline-block;
    padding: 10px 18px;
    background: linear-gradient(135deg, #fff4cc 0%, #ffe066 100%);
    border: 1px solid #f5b301;
    border-radius: 8px;
    color: #5a4500;
    font-weight: 600;
    font-size: var(--font-size-base);
    cursor: pointer;
    box-shadow: 0 2px 4px rgba(245, 179, 1, 0.15);
    transition: transform 0.15s, box-shadow 0.15s;
}

.favorites-card:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 10px rgba(245, 179, 1, 0.25);
}

/* =========================================================
   System Settings page
   ========================================================= */

.system-settings-page {
    padding: 20px;
    width: 100%;
    box-sizing: border-box;
}

.system-settings-page > h2 {
    margin-top: 0;
    margin-bottom: 16px;
}

/* ================================================================
   PartDetailsImportDialog — table + badge styles
   ================================================================ */
.partsimport-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
}
.partsimport-table th,
.partsimport-table td {
    padding: 6px 10px;
    border-bottom: 1px solid var(--gray-200);
    vertical-align: middle;
}
.partsimport-table tr:nth-child(even) td {
    background: var(--gray-100);
}
.partsimport-partnum {
    font-family: var(--font-mono);
    font-weight: 600;
    color: var(--primary-dark);
}
.partsimport-partnum-search {
    width: 100%;
}
.partsimport-badges {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
}

/* Generic small pill / badge */
.badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: var(--font-size-xs);
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}
.badge-on {
    background: var(--primary);
    color: var(--white);
}
.badge-off {
    background: var(--gray-200);
    color: var(--gray-500);
}

/* Status pills */
.status-ready {
    background: var(--primary-light);
    color: var(--primary-dark);
}
.status-already {
    background: var(--gray-200);
    color: var(--gray-700);
}
.status-nomatch {
    background: #ffeaea;
    color: var(--danger);
}

/* Detail Conflicts scan results — bounded and scrollable so a large scan
   never pushes the fixed-height import dialog off screen. Empty (0 height)
   until the first scan populates it. */
.partdetails-conflicts-container {
    max-height: 280px;
}
.partdetails-conflicts-container:empty {
    max-height: 0;
}

/* PartDetailsManagerDialog — keep dialog within viewport, table scrollable */
.part-details-manager-dialog {
    max-width: 90vw;
    max-height: 85vh;
}
.part-details-manager-dialog .Wt-dialog,
.part-details-manager-dialog > .Wt-dialog {
    max-width: 90vw;
    max-height: 85vh;
}
.part-details-manager-dialog .modal-body,
.part-details-manager-dialog .body {
    overflow: auto;
}
.part-details-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
}
.part-details-table th,
.part-details-table td {
    padding: 6px 10px;
    border-bottom: 1px solid var(--gray-200);
    vertical-align: middle;
}
.part-details-table tr:nth-child(even) td {
    background: var(--gray-100);
}
.partdetails-resolve-action {
    display: flex;
    gap: 6px;
    align-items: center;
}
.partdetails-resolve-action .Wt-lineedit,
.partdetails-resolve-action input {
    width: 140px;
}

/* Inner scroll region for the part-details dialog.
   Wt's WDialog body does not behave as a flex parent under the default
   theme, so a deterministic max-height (viewport-based) is the only
   reliable way to keep the scroll inside the dialog. */
.part-details-scroll {
    max-height: calc(85vh - 180px);
    overflow-y: auto;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* Child-assembly card list — used by MachinePage and AssemblyBomViewer */
.child-cards {
    padding: 4px 0;
    background: #fff;
}
.child-card {
    padding: 5px 12px;
    cursor: pointer;
    border-bottom: 1px solid #f1f1f1;
}
.child-card:hover { background: #f0f7f4; }
.child-card-name {
    color: #198754;
    font-weight: 500;
    font-size: .9em;
}
.child-card-badge {
    vertical-align: middle;
    margin-right: 8px;
}
.child-card-badge.is-empty {
    margin: 0 14px 0 6px;
}
.child-card-code {
    color: #999;
    font-size: .78em;
    margin-left: 8px;
}
.child-card-unresolved { cursor: default; }
.child-card-unresolved:hover { background: transparent; }
.child-card-unresolved .child-card-name { color: #888; font-weight: 400; }
/* Highlight applied by AssemblyBomViewer::highlightRowByCode */
.child-card-highlight { background: #e2f0e9 !important; }

/* Sub-assemblies toggle: right-pointing arrow that sits on the horizontal
   resizer strip. Clicking it collapses the card list rendered above the
   resizer; the button stays visible so the list can be re-expanded. */
.sub-assemblies-toggle-btn {
    width: 24px;
    height: 12px;
    line-height: 1;
    padding: 0;
    margin: 0;
    font-size: calc(9px * var(--font-scale));
    color: #6c757d;
    background: #fff;
    border: 1px solid #d8dee4;
    border-radius: 0 0 4px 4px;
    cursor: pointer;
    position: relative;
    top: -1px;
}
.sub-assemblies-toggle-btn:hover {
    color: #198754;
    background: #eef7f2;
    border-color: #198754;
}
.child-cards-outer {
    padding: 4px 0;
    background: #fff;
    min-height: 0;
    overflow: auto;
}

.viewer-wrapper > .child-cards-outer {
    flex: 0 0 auto;
    max-height: 38%;
    min-height: 0;
    overflow-y: auto;
}

.bom-wrapper > .child-cards-outer {
    height: 100%;
    max-height: none;
}

/* Sub-assemblies collapse is handled in C++ via Wt's setHidden() plus
   a modifier class on viewerContainer_. When the list is hidden the
   BOM container is also hidden, which leaves the SVG viewer-wrapper
   as the only flex child; .viewer-wrapper-expanded forces it to take
   the full column. */
.viewer-wrapper.viewer-wrapper-expanded {
    flex: 1 1 100% !important;
    min-height: 0 !important;
}

/* Add-to-Cart dialog: two-cell part info row with label-on-top, value
   below, and a centred quantity stepper with explicit +/- buttons. */
.add-cart-info-row {
    display: flex;
    gap: 24px;
    margin-bottom: 6px;
}
.add-cart-info-cell {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.add-cart-info-label {
    font-size: 0.78em;
    color: #6c757d;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.add-cart-info-value {
    font-weight: 500;
    font-size: 1em;
    color: #212529;
}
.add-cart-qty-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin-top: 10px;
}
.add-cart-qty-label {
    font-weight: 500;
    min-width: 80px;
}
.add-cart-qty-stepper {
    display: inline-flex;
    align-items: stretch;
    height: 34px;
    border: 1px solid #ced4da;
    border-radius: 4px;
    overflow: hidden;
    background: #fff;
}
.add-cart-qty-stepper .add-cart-qty-btn {
    width: 34px;
    height: 34px;
    margin: 0;
    padding: 0;
    border: 0;
    background: #f1f3f5;
    color: #212529;
    font-size: 1.2em;
    font-weight: 600;
    line-height: 1;
    border-radius: 0;
    cursor: pointer;
}
.add-cart-qty-stepper .add-cart-qty-btn:hover {
    background: #e9ecef;
}
.add-cart-qty-stepper .add-cart-qty-input {
    width: 60px;
    height: 34px;
    border: 0;
    border-left: 1px solid #ced4da;
    border-right: 1px solid #ced4da;
    border-radius: 0;
    text-align: center;
    font-size: 1em;
    font-weight: 500;
    margin: 0;
    padding: 0 6px;
    box-sizing: border-box;
}

.maint-qty-rounded-hint {
    font-size: .8em;
    opacity: .75;
    margin-top: 2px;
}

.maint-qty-line {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: nowrap;
    gap: 6px;
}

.maint-qty-unit {
    flex: 0 0 auto;
    white-space: nowrap;
}

.maint-unit-missing {
    display: block;
    margin-top: 2px;
    font-size: .8em;
    color: #b45309;
    white-space: normal;
}

.bom-bulk-add-dialog .maint-qty-rounded-hint {
    display: block;
    white-space: normal;
}

.bom-bulk-add-dialog .bom-bulk-add-scroll {
    overflow-x: auto;
}

.bom-bulk-add-dialog .Wt-dialog-contents {
    overflow: visible !important;
}

.bom-bulk-add-content {
    max-height: 70vh;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 20px;
    box-sizing: border-box;
    overflow: hidden;
}

.bom-bulk-add-scroll {
    flex: 1 1 auto;
    min-height: 80px;
    overflow: auto;
    padding-right: 4px;
}

.bom-bulk-add-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}

.bom-bulk-add-table th,
.bom-bulk-add-table td {
    padding: 8px 10px;
    border-bottom: 1px solid #e9ecef;
    vertical-align: middle;
}

.bom-bulk-add-table th {
    background: #f1f3f4;
    color: #5f6b76;
    font-weight: 700;
}

.bom-bulk-add-table th:nth-child(1) { width: 44px; text-align: center; }
.bom-bulk-add-table th:nth-child(2) { width: 24%; }
.bom-bulk-add-table th:nth-child(3) { width: auto; }
.bom-bulk-add-table th:nth-child(4) { width: 200px; text-align: center; }
.bom-bulk-add-table th:nth-child(5) { width: 36px; }

.bom-bulk-add-remove-cell {
    text-align: center;
    padding-left: 2px !important;
    padding-right: 2px !important;
}

.bom-bulk-add-remove {
    width: 16px;
    height: 16px;
    cursor: pointer;
    opacity: 0.6;
    vertical-align: middle;
}

.bom-bulk-add-remove:hover {
    opacity: 1;
}

.bom-bulk-add-image-cell {
    text-align: center;
    padding-left: 4px !important;
    padding-right: 4px !important;
}

.bom-bulk-add-image {
    width: 28px;
    height: 28px;
    object-fit: contain;
    border-radius: 3px;
    border: 0;
    background: #f8f9fa;
    vertical-align: middle;
}

.bom-bulk-add-qty-cell {
    text-align: center;
    min-width: 190px;
}

.bom-bulk-add-dialog .dialog-buttons {
    flex: 0 0 auto;
    margin-top: 0;
    padding-top: 12px;
    border-top: 1px solid #e9ecef;
    background: #fff;
    overflow: visible !important;
}

.bom-bulk-add-submit,
.bom-bulk-add-cancel {
    min-width: 128px;
    height: 34px;
}

/* ============================================
   FULL-LIST MODE: BOM expands to full height;
   center column scrolls as one long page.
   Toggled by adding .full-list-mode to
   #centerContentArea via the bar button.
   ============================================ */
#centerContentArea.full-list-mode {
    overflow-y: auto !important;
}
#centerContentArea.full-list-mode .viewer-wrapper {
    flex: 0 0 auto !important;
    height: 50vh !important;
    overflow: hidden !important;
}
#centerContentArea.full-list-mode .bom-wrapper {
    flex: 0 0 auto !important;
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
}
#centerContentArea.full-list-mode .horizontal-resizer {
    display: none !important;
}

/* Viewer collapsed: no visual present, BOM fills the center area.
   The wrapper shrinks to content height (files bar only or zero),
   letting .bom-wrapper (flex-grow:1) absorb all remaining space. */
.viewer-wrapper.viewer-collapsed {
    flex: 0 0 auto !important;
    height: auto !important;
    min-height: 0 !important;
}

/* Full-list mode toggle — SVG icon driven by CSS state.
   Table mode: expand icon. .full-list-mode: collapse icon. */
.bom-mode-toggle {
    min-width: 28px;
    min-height: 24px;
    /* !important overrides .btn-icon's `background: transparent !important`. */
    background-image: url('../files/essentials/bom-expand.svg') !important;
    background-repeat: no-repeat !important;
    background-position: center !important;
    background-size: 16px 16px !important;
}
#centerContentArea.full-list-mode .bom-mode-toggle {
    background-image: url('../files/essentials/bom-collapse.svg') !important;
}

/* User menu price display options: radio dot before each label. */
.price-display-menu .price-display-option .Wt-item::before,
.price-display-menu .price-display-option a::before {
    content: "";
    flex: 0 0 12px;
    width: 12px;
    height: 12px;
    border: 2px solid var(--gray-400);
    border-radius: 50%;
    box-sizing: border-box;
}
.price-display-menu .price-display-option.is-active .Wt-item::before,
.price-display-menu .price-display-option.is-active a::before {
    border-color: var(--success);
    background: radial-gradient(circle, var(--success) 0 3px, transparent 3.5px);
}

/* Price values: purchase price (EK) in the price green, list price muted blue-grey. */
.bom-table td.bom-price-col {
    color: var(--success);
    font-weight: 600;
}
.bom-table td.bom-listprice-col {
    color: #5b7a99;
    font-weight: 400;
}

/* List price line under the purchase price in the part info sidebar. */
.info-value.info-list-price {
    color: #5b7a99;
}

/* List price line under the own price in the cart price cell. grid-column
   keeps it in the value column of the mobile card grid. */
.cart-items-table td.cart-price-cell .cart-list-price {
    display: block;
    grid-column: 2;
    color: #5b7a99;
    font-weight: 400;
    font-size: 0.85em;
}

/* Phones: full-list mode is permanent and the toggle is removed, so the BOM
   never sits in a nested scroll area. Declared without .full-list-mode so the
   class reset on navigation cannot drop it. The collapsed (no drawing) and
   expanded (BOM hidden) viewer states keep their own heights. */
@media only screen and (max-width: 768px),
       (hover: none) and (pointer: coarse) and (max-height: 600px) {
    #centerContentArea {
        overflow-y: auto !important;
    }
    #centerContentArea .viewer-wrapper:not(.viewer-collapsed):not(.viewer-wrapper-expanded) {
        flex: 0 0 auto !important;
        height: 50vh !important;
        overflow: hidden !important;
    }
    #centerContentArea .bom-wrapper {
        flex: 0 0 auto !important;
        height: auto !important;
        max-height: none !important;
        overflow: visible !important;
    }
    #centerContentArea .horizontal-resizer {
        display: none !important;
    }
    .bom-mode-toggle {
        display: none !important;
    }
}

/* Retrofit kit machine-number pill chip (plain WText, no raw HTML). */
.retrofit-machine-chip {
    display: inline-block;
    padding: 2px 10px;
    background: #f0f8f3;
    border: 1px solid #198754;
    border-radius: 16px;
    color: #198754;
    font-size: 0.85em;
    font-weight: 500;
}

/* EN / DE language badge in the description section. */
.retrofit-lang-badge {
    display: inline-block;
    background: #e8f5e9;
    color: #198754;
    padding: 1px 6px;
    border-radius: 3px;
    font-size: 0.75em;
    font-weight: 700;
    flex-shrink: 0;
}

/* Quick-access stays visible on mobile; horizontal scroll handles overflow. */
@media only screen and (max-width: 768px) {
    .home-quick-access { overflow-x: auto; }
}

/* Mantis ticket dialog body — normal block flow, no overlap. */
/* Self-centering modal: stays centered even when the async screenshot enlarges
   the body after open (Wt only re-centers on window resize; the transform
   re-centers on every reflow against the element's own size). */
.Wt-dialog.mantis-report-dialog,
div.Wt-dialog.mantis-report-dialog {
    position: fixed !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    /* Never exceed the viewport: width caps at 900px on wide screens and
       shrinks to 94vw on narrow ones so the right-edge buttons never overflow.
       Leaves ~7vh clear above and below the centered dialog. */
    width: 94vw !important;
    max-width: 900px !important;
    max-height: 86vh !important;
}

/* Title bar as a flex row so Send + close stay inside the rounded corner
   instead of overflowing the right edge (float-right clipped them). The title
   shrinks (ellipsis) before the fixed-size buttons do. */
.Wt-dialog.mantis-report-dialog .titlebar,
.Wt-dialog.mantis-report-dialog .Wt-dialog-title-bar {
    display: flex !important;
    align-items: center !important;
    gap: 8px !important;
}
.Wt-dialog.mantis-report-dialog .titlebar > :first-child,
.Wt-dialog.mantis-report-dialog .Wt-dialog-title-bar > :first-child {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mantis-report-dialog .mantis-header-send  { float: none !important; order: 1; margin: 0 !important; flex: 0 0 auto; }
.mantis-report-dialog .mantis-header-close { float: none !important; order: 2; margin: 0 !important; flex: 0 0 auto; }

.mantis-dialog-body { padding: 18px; max-height: 72vh; overflow-y: auto; overflow-x: auto; }
.mantis-dialog-body > * { display: block; margin: 0 0 8px; }
.mantis-dialog-body .edit-input,
.mantis-dialog-body .edit-textarea { width: 100%; box-sizing: border-box; }

/* Dialog body is the single scroll owner, on both axes: a zoomed-in canvas is
   panned here rather than in a nested box. Answers the generic
   .edit-dialog .body / .body > div !important rules (line ~10852) with
   equal-specificity !important rules that win by file order. */
.Wt-dialog.mantis-report-dialog .mantis-dialog-body {
    display: block !important;
    height: auto !important;
    max-height: 78vh !important;
    overflow-y: auto !important;
    overflow-x: auto !important;
}
/* Neutralizes the generic ".body > div" scroll rule, which otherwise turns the
   annotation box into a second, nested scroll box inside the scrolling body. */
.Wt-dialog.mantis-report-dialog .mantis-dialog-body > div {
    max-height: none !important;
    overflow: visible !important;
}

/* Hidden field carrying the annotated image; off-screen but still form-synced. */
.mantis-anno-hidden { position: absolute !important; left: -9999px !important;
    width: 1px; height: 1px; opacity: 0; }

/* Mantis ticket annotation widget */
.mantis-anno {
    margin-top: 6px;
    border: 1px solid #e0e0e0;
    border-radius: 6px;
    padding: 8px;
    background: #fafafa;
}
/* Full-screen loading overlay shown while the ticket screenshot is captured.
   Marked data-html2canvas-ignore so it is excluded from the captured image. */
.mantis-load-overlay {
    position: fixed;
    inset: 0;
    z-index: 100000;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    background: rgba(255, 255, 255, .6);
    backdrop-filter: blur(1px);
}
.mantis-load-spin {
    width: 46px;
    height: 46px;
    border: 4px solid rgba(25, 135, 84, .25);
    border-top-color: #198754;
    border-radius: 50%;
    animation: btn-spin .7s linear infinite;
}
.mantis-load-txt {
    font-size: calc(14px * var(--font-scale));
    color: #198754;
    font-weight: 600;
}
/* Send-result states shown inside the loading overlay. */
.mantis-load-ok { font-size: calc(16px * var(--font-scale)); font-weight: 700; color: var(--primary); }
.mantis-load-err { font-size: calc(15px * var(--font-scale)); font-weight: 600; color: #dc3545; }
.mantis-anno-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-bottom: 6px;
}
.mantis-tool {
    border: 1px solid var(--primary);
    background: var(--white);
    color: var(--primary);
    border-radius: var(--radius-md);
    padding: 4px 12px;
    font-size: calc(13px * var(--font-scale));
    cursor: pointer;
    transition: background var(--transition-slow), color var(--transition-slow);
}
.mantis-tool:hover { background: rgba(25, 135, 84, .1); }
.mantis-tool.active {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--white);
}
.mantis-tool.active:hover { background: var(--primary-dark); }
/* Green slider bars (pen size + detail zoom) to match the system accent. */
.mantis-anno-toolbar input[type=range] { accent-color: var(--primary); }
.mantis-anno-toolbar input[type=color] {
    width: 28px;
    height: 24px;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 0;
    cursor: pointer;
}
/* Plain frame around the annotation canvas — deliberately not a scroll box.
   The dialog body is the only scroll container, so a zoomed canvas is panned
   with the body's own scrollbars instead of a nested set. */
.mantis-anno-view {
    width: 100%;
    overflow: visible;
    box-sizing: border-box;
    border: 1px solid #ddd;
    border-radius: 4px;
    background: #fff;
}
.mantis-anno-canvas {
    display: block;
    width: auto;
    height: auto;
    background: #fff;
    cursor: crosshair;
}
/* "Assembly view" button above the annotation toolbar. */
.mantis-asmview-btn { display: inline-block; margin-bottom: 8px; font-weight: 600; }
/* Toolbar zoom controls (view zoom, independent of the detail magnifier). */
.mantis-zoombtn { padding: 4px 9px; min-width: 30px; font-weight: 600; }
.mantis-anno-sep {
    display: inline-block;
    width: 1px;
    height: 20px;
    background: #ccc;
    margin: 0 3px;
}
/* Send button hosted in the green dialog title bar — always visible. */
.mantis-header-send {
    float: right;
    margin: -2px 0 0 8px;
    background: #fff;
    color: #1b7a44;
    border: none;
    border-radius: 4px;
    padding: 6px 18px;
    font-weight: 600;
    cursor: pointer;
}
.mantis-header-send:hover { background: #eafaf0; }

/* Close (✕) in the green title bar, far-right corner. */
.mantis-header-close {
    float: right;
    margin: -2px 0 0 4px;
    background: transparent;
    border: none;
    border-radius: 4px;
    padding: 6px 8px;
    cursor: pointer;
}
.mantis-header-close:hover { background: rgba(255, 255, 255, 0.18); }
.mantis-header-close img { width: 18px; height: 18px; filter: brightness(0) invert(1); }

/* 3D viewer brightness slider: green filled track (set via inline gradient in
   JS) + green thumb. */
.tjs-bright {
    -webkit-appearance: none;
    appearance: none;
    height: 6px;
    border-radius: 3px;
    background: #ccc;
    outline: none;
    cursor: pointer;
}
.tjs-bright::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--primary);
    border: none;
    cursor: pointer;
}
.tjs-bright::-moz-range-thumb {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--primary);
    border: none;
    cursor: pointer;
}
.tjs-bright::-moz-range-progress {
    background: var(--primary);
    height: 6px;
    border-radius: 3px;
}

/* 3D viewer measurement UI (threejsviewer.js) */
.tjs-status {
    position: absolute; bottom: 10px; left: 10px; z-index: 5; display: none;
    background: rgba(15,23,42,0.85); color: #fff; border-radius: 6px;
    padding: 6px 10px; font-size: calc(13px * var(--font-scale)); line-height: 1.35; max-width: 60%;
}
.tjs-mlabel {
    position: absolute; z-index: 6; display: none; transform: translate(-50%, -50%);
    background: rgba(15,23,42,0.9); color: #fff; border-radius: 6px;
    padding: 4px 8px; font-size: calc(12px * var(--font-scale)); line-height: 1.3; white-space: nowrap;
    pointer-events: none; box-shadow: 0 1px 4px rgba(0,0,0,0.35);
}
.tjs-mlabel.tjs-hi { outline: 2px solid #00ffaa; }
.tjs-badge {
    position: absolute; z-index: 7; pointer-events: none;
    background: rgba(15,23,42,0.92); color: #fff; border-radius: 4px;
    padding: 2px 6px; font-size: calc(11px * var(--font-scale)); font-weight: 600; white-space: nowrap;
}
.tjs-views {
    position: absolute; top: 52px; right: 10px; z-index: 5;
    display: flex; flex-direction: column; gap: 4px; align-items: stretch;
}
.tjs-viewbtn {
    border: 1px solid #ccc; border-radius: 6px; background: #fff;
    color: var(--primary); font-size: calc(11px * var(--font-scale)); font-weight: 600;
    padding: 3px 8px; cursor: pointer; white-space: nowrap;
}
.tjs-viewbtn:hover { background: #eefaf3; }
.tjs-secslider { width: 110px; }
.tjs-color-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 24px;
    margin: 0 0 5px;
    padding: 0 8px;
    border: 1px solid rgba(25, 135, 84, 0.45);
    border-radius: 5px;
    background: var(--primary);
    color: var(--white);
    font-size: calc(11px * var(--font-scale));
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}
.tjs-color-controls-body {
    display: block;
}
.tjs-color-controls.tjs-collapsed {
    background: transparent !important;
    border-color: transparent !important;
    box-shadow: none !important;
    padding: 0 !important;
}
.tjs-color-controls.tjs-collapsed .tjs-color-toggle {
    width: auto;
    margin: 0;
    background: var(--white);
    color: var(--primary);
    box-shadow: 0 1px 3px rgba(15, 81, 50, 0.12);
}
.tjs-color-controls.tjs-collapsed .tjs-color-controls-body {
    display: none !important;
}
.tjs-panel {
    position: absolute; bottom: 10px; right: 10px; z-index: 6;
    width: 250px; max-height: 60%; overflow: hidden;
    background: rgba(255,255,255,0.95); border: 1px solid #ccc; border-radius: 8px;
    font-size: calc(12px * var(--font-scale)); box-shadow: 0 2px 8px rgba(0,0,0,0.2);
    display: flex; flex-direction: column;
}
.tjs-panel-hd {
    display: flex; align-items: center; gap: 6px; padding: 6px 8px;
    background: var(--primary); color: #fff; font-weight: 600; cursor: pointer;
}
.tjs-panel-hd .tjs-title { flex: 1; }
.tjs-panel-hd .tjs-clear {
    background: rgba(255,255,255,0.2); color: #fff; border: none; border-radius: 4px;
    padding: 2px 8px; cursor: pointer; font-size: calc(11px * var(--font-scale));
}
.tjs-panel-hd .tjs-clear:hover { background: rgba(255,255,255,0.35); }
.tjs-panel-body { overflow-y: auto; }
.tjs-row {
    display: flex; align-items: flex-start; gap: 6px; padding: 5px 8px;
    border-top: 1px solid #eee;
}
.tjs-row:hover { background: #eefaf3; }
.tjs-row .tjs-val { flex: 1; line-height: 1.35; }
.tjs-copyable { cursor: pointer; }
.tjs-copyable:hover { text-decoration: underline; }
.tjs-row .tjs-del {
    background: none; border: none; color: #b00; cursor: pointer;
    font-size: calc(14px * var(--font-scale)); line-height: 1; padding: 0 2px;
}

@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
    .tjs-color-controls {
        top: 44px !important;
        left: 8px !important;
        max-width: calc(100vw - 16px);
        box-sizing: border-box;
        padding: 4px 6px !important;
    }

    .tjs-color-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 0;
        height: 28px;
        margin: 0;
        padding: 0 10px;
        border: 1px solid rgba(25, 135, 84, 0.45);
        border-radius: 5px;
        background: var(--white);
        color: var(--primary);
        font-size: calc(12px * var(--font-scale));
        font-weight: 700;
        line-height: 1;
        cursor: pointer;
        box-shadow: 0 1px 3px rgba(15, 81, 50, 0.12);
    }

    .tjs-color-controls:not(.tjs-collapsed) .tjs-color-toggle {
        width: 100%;
        margin-bottom: 5px;
        background: var(--primary);
        color: var(--white);
        border-color: var(--primary);
    }

    .tjs-color-controls.tjs-collapsed {
        background: transparent !important;
        border-color: transparent !important;
        box-shadow: none !important;
        padding: 0 !important;
    }

    .tjs-color-controls.tjs-collapsed .tjs-color-controls-body {
        display: none !important;
    }

    .tjs-color-controls:not(.tjs-collapsed) .tjs-color-controls-body {
        display: block !important;
        max-width: 180px;
    }

    .tjs-color-controls .tjs-bright {
        width: 94px !important;
    }
}

.mantis-anno-capture { margin-bottom: 6px; }
.mantis-anno-attach { margin-top: 6px; }
.mantis-anno-attach.attached {
    background: #2e7d32;
    border-color: #2e7d32;
    color: #fff;
}

/* Large monitor used in portrait: keep the Assemblies tree as a full-height
   left column and stack the right column as
   assembly-bar -> Part Info -> SVG -> BOM.
   The assembly bar and the SVG/BOM block live inside .panel-center while Part
   Info is a sibling, so `.panel-center { display: contents }` promotes the
   center's children into the outer grid, letting all four be ordered together.
   min-width:1025px keeps this clear of the tablet/mobile rules (<=1024/768px). */
/* Portrait stacked layout runs down to the mobile breakpoint (>=769px) so
   there is no dead zone between 768 and 1025 where it reverts to the desktop
   grid and flip-flops orientation while resizing. */
@media (orientation: portrait) and (min-width: 769px) {
    .machine-page-layout {
        display: grid;
        grid-template-columns: auto 1fr;              /* col1 = tree, col2 = stacked content */
        grid-template-rows: auto auto minmax(0, 1fr); /* bar / part-info / svg+bom */
    }
    .machine-page-layout > .panel-left {
        grid-column: 1;
        grid-row: 1 / 4;                              /* tree spans the whole left side */
    }
    /* Dissolve the center wrapper so its children join the outer grid. */
    .machine-page-layout > .panel-center {
        display: contents !important;
    }
    .machine-page-layout > .panel-center > .assembly-bar {
        grid-column: 2;
        grid-row: 1;                                  /* green context bar on top */
    }
    .machine-page-layout > .part-info-sidebar {
        grid-column: 2;
        grid-row: 2;                                  /* Part Info under the bar */
        position: static;                             /* clear fixed positioning from mobile rules */
        width: 100% !important;                       /* beat inline width set by the resizer JS */
        min-width: 0;
        max-width: none;
        height: 340px;                                /* definite height so the right table can scroll */
        max-height: 340px;
        overflow: hidden;                             /* inner columns handle the scroll */
        border-left: none;
        border-bottom: 1px solid #e0e0e0;
    }
    .machine-page-layout > .part-info-sidebar.collapsed {
        height: 0 !important;                         /* collapse toggle -> hide the strip */
        min-height: 0;
        max-height: 0;
    }
    /* Compact horizontal Part Info: headblock (+small image) on the left,
       spec table scrollable on the right, so the strip stays short. */
    .machine-page-layout > .part-info-sidebar .part-info-content {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);  /* spec table (content-sized) | card+image (flexes) */
        grid-template-rows: auto minmax(0, 1fr);     /* headblock sizes to content, image fills the rest */
        gap: 10px 18px;
        overflow: hidden;
        height: 100%;                                 /* fill the fixed-height strip */
    }
    .machine-page-layout > .part-info-sidebar .part-info-headblock {
        grid-column: 2;
        grid-row: 1;
    }
    .machine-page-layout > .part-info-sidebar .part-info-image-container {
        grid-column: 2;
        grid-row: 2;
        min-height: 0;
        overflow: hidden;
        display: flex;                                /* center + scale the photo to fit */
        align-items: center;
        justify-content: center;
    }
    .machine-page-layout > .part-info-sidebar .part-info-image {
        max-height: 100%;                             /* scale to the left column, never clipped */
        max-width: 100%;
        object-fit: contain;
    }
    .machine-page-layout > .part-info-sidebar .part-info-table {
        grid-column: 1;
        grid-row: 1 / 3;                              /* spec table on the left, matches the card height */
        display: block;                               /* block table -> scrollable overflow */
        overflow-y: auto;
        min-height: 0;
        align-self: stretch;
    }
    .machine-page-layout > .part-info-sidebar .part-info-empty {
        grid-column: 1 / 3;
    }
    /* The dark title bar is redundant here (assembly bar above gives context);
       hide it and reveal the card's mirrored pin + close next to the star. */
    .machine-page-layout > .part-info-sidebar .part-info-header {
        display: none !important;
    }
    .machine-page-layout > .part-info-sidebar .part-info-card-pin,
    .machine-page-layout > .part-info-sidebar .part-info-card-close {
        display: flex !important;
    }
    /* Denser spec table so the strip stays short. */
    .machine-page-layout > .part-info-sidebar .part-info-table td {
        padding: 3px 8px;
        font-size: calc(11px * var(--font-scale));
    }
    .machine-page-layout > .part-info-sidebar .part-info-table .info-label {
        font-size: calc(10px * var(--font-scale));
    }
    .machine-page-layout > .panel-center > .center-content-area {
        grid-column: 2;
        grid-row: 3;                                  /* SVG + BOM fill the rest */
        min-width: 0;
        min-height: 0;
    }
    .machine-page-layout > .panel-resizer.vertical-resizer {
        display: none;                                /* left/right drag handles don't map to the grid */
    }
    /* Split the center height by ratio; the default vh-based flex-basis starves
       the SVG when the grid row height differs from the viewport height. */
    #centerContentArea .viewer-wrapper {
        flex: 3 1 0 !important;
        min-height: 220px !important;
    }
    #centerContentArea .bom-wrapper {
        flex: 2 1 0 !important;
        min-height: 160px !important;
    }
    /* MantisHub screenshot: html2canvas can't render the display:contents
       center subtree, so the SVG + BOM come out blank. During capture (toggled
       behind the full-screen overlay in doCapture) give panel-center a real box
       and stack Part Info above it so both are captured. */
    .machine-page-layout.mantis-capturing > .panel-center {
        display: flex !important;
        flex-direction: column;
        grid-column: 2;
        grid-row: 2;
        min-height: 0;
    }
    .machine-page-layout.mantis-capturing > .part-info-sidebar {
        grid-row: 1;
    }
    .machine-page-layout.mantis-capturing #centerContentArea .viewer-wrapper {
        min-height: 60vh !important;
    }
    /* Expand the BOM to its full natural height during capture so every row is
       in the shot; otherwise only the few scrolled-into-view rows are drawn and
       the list looks shrunk. */
    .machine-page-layout.mantis-capturing #centerContentArea .bom-wrapper,
    .machine-page-layout.mantis-capturing #centerContentArea .bom-viewer-container,
    .machine-page-layout.mantis-capturing #centerContentArea .bom-table-wrapper {
        flex: none !important;
        min-height: 0 !important;
        max-height: none !important;
        height: auto !important;
        overflow: visible !important;
    }
}

/* Mobile Safari zooms the whole page when focused form controls render below
   16px. Keep touch controls at that floor without disabling pinch zoom. */
@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
    html {
        -webkit-text-size-adjust: 100%;
    }

    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
    select,
    textarea,
    .Wt-lineedit,
    .Wt-combobox,
    .Wt-spinbox input,
    .edit-input,
    .edit-textarea,
    .edit-inline-input,
    .dialog-input-full,
    .search-input,
    .search-page-input,
    .machine-dropdown,
    .company-switch,
    .assembly-bar-dropdown,
    .assembly-bar-version select,
    .cart-selector,
    .cart-search-input,
    .favorites-search-input,
    .cart-qty-input,
    .part-info-qty,
    .vis-range-input,
    .add-cart-qty-input,
    .add-cart-qty-stepper .add-cart-qty-input {
        /* 16px floor: below it iOS Safari zooms the page on focus. */
        font-size: max(16px, calc(16px * var(--font-scale))) !important;
    }
}

/* Keep the 3D viewer dialog as a real viewport-sized canvas. This final block
   intentionally wins over the generic mobile WDialog card rules above. */
.Wt-dialog.threejs-viewer-popup,
div.Wt-dialog.threejs-viewer-popup,
body div.Wt-dialog.threejs-viewer-popup {
    width: min(96vw, 1500px) !important;
    max-width: 1500px !important;
    height: min(90vh, 960px) !important;
    max-height: 94vh !important;
}

.threejs-viewer-popup .threejs-viewer-popup-body,
.threejs-viewer-popup > .Wt-dialog-contents,
.threejs-viewer-popup > .contents {
    display: flex !important;
    flex-direction: column !important;
    min-height: 0 !important;
    height: 100% !important;
    overflow: hidden !important;
}

.threejs-viewer-popup .body,
.threejs-viewer-popup .Wt-dialog-body {
    min-height: 0 !important;
    height: 100% !important;
    overflow: hidden !important;
}

.threejs-viewer-popup .threejs-viewer-wrap {
    flex: 1 1 auto !important;
    min-height: 320px !important;
    height: auto !important;
}

@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
    .Wt-dialog.threejs-viewer-popup,
    div.Wt-dialog.threejs-viewer-popup,
    body div.Wt-dialog.threejs-viewer-popup {
        width: 96vw !important;
        max-width: 96vw !important;
        height: 88dvh !important;
        min-height: 420px !important;
        max-height: 92dvh !important;
    }

    .threejs-viewer-popup .threejs-viewer-wrap {
        min-height: 300px !important;
    }
}

/* Mobile part-info actions: pinning is a desktop affordance, while close must
   be easy to hit with a thumb. Keep this final so older portrait/sidebar rules
   cannot shrink the buttons back down. */
@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
    .part-info-sidebar .part-info-pin-btn,
    .part-info-sidebar .part-info-card-pin {
        display: none !important;
    }

    /* Single close on phones: hide the card's mirrored close, keep the
       header's thumb-sized one (portrait-tablet keeps the card close via a
       higher-specificity rule, so it is unaffected here). */
    .part-info-sidebar .part-info-card-close {
        display: none !important;
    }

    .part-info-sidebar .part-info-close-btn {
        display: flex !important;
        align-items: center !important;
        justify-content: center !important;
        flex: 0 0 40px !important;
        width: 40px !important;
        min-width: 40px !important;
        height: 40px !important;
        min-height: 40px !important;
        padding: 0 !important;
        border-radius: 8px !important;
        font-size: calc(24px * var(--font-scale)) !important;
        line-height: 1 !important;
    }
}

/* ============================================================
   Send-order dialog — single authoritative layout contract.
   Placed last so it wins over the earlier .send-order-dialog
   blocks. Owns: dialog size, scroll ownership, title bar, the
   two-column grid, delivery-type options and the full-width
   pinned footer.
   ============================================================ */
body div.Wt-dialog.send-order-dialog,
.Wt-dialog.send-order-dialog {
    position: fixed !important;
    top: 50% !important;
    left: 50% !important;
    right: auto !important;
    bottom: auto !important;
    width: min(96vw, 1000px) !important;
    min-width: 0 !important;
    max-width: 96vw !important;
    height: auto !important;
    /* min-height MUST be reset: the generic mobile WDialog rule sets
       min-height:100vh, and min-height beats max-height, which would force the
       card past the viewport, leave scrollHeight == clientHeight (no scrollbar
       at all) and push the footer off-screen. */
    min-height: 0 !important;
    max-height: 88dvh !important;
    margin: 0 !important;
    border-radius: 12px !important;
    transform: translate(-50%, -50%) !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
}
/* Title bar fills the full width across Wt title-bar class variants. */
.Wt-dialog.send-order-dialog .titlebar,
.Wt-dialog.send-order-dialog .Wt-dialog-titlebar,
.Wt-dialog.send-order-dialog .Wt-dialog-title-bar {
    display: block !important;
    width: 100% !important;
    box-sizing: border-box !important;
    align-self: stretch !important;
    flex: 0 0 auto !important;
}
/* Wt renders this dialog as .Wt-dialog > .dialog-layout > (.titlebar, .body),
   where .body is also .cart-dialog-content (contents() IS the body element).
   .dialog-layout carries inline `display:flex; flex-flow:column` but no flex
   sizing, so it defaults to flex:0 1 auto / min-height:auto and grows to its
   content. The body then never overflows, no scrollbar is generated, and
   .Wt-dialog merely clips the overflow -- leaving the lower form unreachable.
   flex:1 + min-height:0 here is what makes the body a real scroll port.
   The other two selectors are Wt-version fallbacks. */
.Wt-dialog.send-order-dialog .dialog-layout,
.Wt-dialog.send-order-dialog .Wt-dialog-contents,
.Wt-dialog.send-order-dialog .contents {
    display: flex !important;
    flex: 1 1 auto !important;
    flex-direction: column !important;
    min-height: 0 !important;
    max-height: none !important;
    overflow: hidden !important;
}
/* The scroll owner. Deliberately a BLOCK box: making this a flex column makes
   its children shrink to fit instead of overflowing, so no scrollbar is ever
   generated and the lower content becomes unreachable.
   `.body` and `.cart-dialog-content` may resolve to the SAME element (Wt's
   contents() is the body), so these rules are written to hold either way:
   whichever element ends up as the wrapper's flex child gets flex:1 +
   min-height:0 and scrolls; a separate inner one just flows at height:auto. */
.Wt-dialog.send-order-dialog .body,
.Wt-dialog.send-order-dialog .Wt-dialog-body,
.Wt-dialog.send-order-dialog .cart-dialog-content {
    display: block !important;
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: auto !important;
    max-height: none !important;
    overflow-x: hidden !important;
    overflow-y: auto !important;
}
.Wt-dialog.send-order-dialog .body,
.Wt-dialog.send-order-dialog .Wt-dialog-body {
    padding: 0 !important;
}
.Wt-dialog.send-order-dialog .cart-dialog-content {
    width: 100% !important;
    box-sizing: border-box !important;
    padding: 20px 22px 0 !important;
}
/* Two-column grid; collapses to one column on narrow screens. */
.Wt-dialog.send-order-dialog .send-order-columns {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) !important;
    gap: 26px !important;
    align-items: start !important;
    margin-top: 14px !important;
}
.Wt-dialog.send-order-dialog .send-order-products-column,
.Wt-dialog.send-order-dialog .send-order-details-column {
    min-width: 0 !important;
    position: static !important;
}
.Wt-dialog.send-order-dialog .send-order-products-column .checkout-items {
    max-height: min(46dvh, 410px) !important;
    overflow-y: auto !important;
}
/* Product rows: thumbnail | name+number | qty+line total. */
.Wt-dialog.send-order-dialog .checkout-item {
    display: flex !important;
    align-items: center !important;
    gap: 12px !important;
}
.Wt-dialog.send-order-dialog .checkout-item-thumb {
    flex: 0 0 auto !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    width: 44px !important;
    height: 44px !important;
    border: 1px solid var(--border-color, #e2e6ea) !important;
    border-radius: 8px !important;
    background: var(--white, #fff) !important;
    overflow: hidden !important;
}
.Wt-dialog.send-order-dialog .checkout-item-thumb img {
    max-width: 100% !important;
    max-height: 100% !important;
    object-fit: contain !important;
    display: block !important;
}
.Wt-dialog.send-order-dialog .checkout-item-thumb-empty {
    background: #f2f4f6 !important;
}
.Wt-dialog.send-order-dialog .checkout-item-info {
    flex: 1 1 auto !important;
    min-width: 0 !important;
}
.Wt-dialog.send-order-dialog .checkout-item-right {
    flex: 0 0 auto !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: flex-end !important;
    gap: 2px !important;
}
.Wt-dialog.send-order-dialog .checkout-item-total {
    font-weight: 600 !important;
    font-variant-numeric: tabular-nums;
}
/* Cart total under the product list. */
.Wt-dialog.send-order-dialog .checkout-total-row {
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    margin-top: 12px !important;
    padding-top: 10px !important;
    border-top: 1px solid var(--border-color, #e2e6ea) !important;
    font-weight: 700 !important;
}
.Wt-dialog.send-order-dialog .checkout-total-value {
    font-variant-numeric: tabular-nums;
}
/* Shown when the total cannot cover every line. */
.Wt-dialog.send-order-dialog .checkout-price-note {
    display: block !important;
    margin-top: 10px !important;
    padding: 9px 11px !important;
    border: 1px solid #f0d9a0 !important;
    border-radius: 8px !important;
    background: #fdf6e3 !important;
    color: #7a5c1e !important;
    font-size: calc(12px * var(--font-scale)) !important;
    line-height: 1.45 !important;
}
/* Delivery type: selectable option pills sized to their label; a pill that
   does not fit wraps to the next row and stretches to fill it. */
.Wt-dialog.send-order-dialog .send-order-delivery-types {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 10px !important;
}
.Wt-dialog.send-order-dialog .send-order-delivery-types .radio-pill {
    display: flex !important;
    align-items: center !important;
    gap: 9px !important;
    flex: 1 1 auto !important;
    min-width: 0 !important;
    margin: 0 !important;
    padding: 11px 14px !important;
    border: 1px solid var(--border-color, #e2e6ea) !important;
    border-radius: 9px !important;
    background: var(--white, #fff) !important;
    cursor: pointer !important;
    font-weight: 500 !important;
}
.Wt-dialog.send-order-dialog .send-order-delivery-types .radio-pill:hover {
    border-color: #b7c0c9 !important;
}
.Wt-dialog.send-order-dialog .send-order-delivery-types .radio-pill:has(input:checked) {
    border-color: var(--primary) !important;
    background: color-mix(in srgb, var(--primary) 8%, transparent) !important;
}
.Wt-dialog.send-order-dialog .send-order-delivery-types .radio-pill input {
    margin: 0 !important;
    width: 16px;
    height: 16px;
    accent-color: var(--primary);
    flex: 0 0 auto;
}
.Wt-dialog.send-order-dialog .send-order-delivery-types .radio-pill label {
    margin: 0 !important;
    cursor: pointer !important;
    min-width: 0 !important;
    white-space: normal !important;
}
/* Fixed pick-up address: read-only text under its label. */
.Wt-dialog.send-order-dialog .send-order-pickup-location {
    display: block;
    color: var(--gray-800);
}
/* Pick-up date field: opens the calendar popup, so it reads as a picker. */
.Wt-dialog.send-order-dialog .pickup-date-input {
    cursor: pointer !important;
    padding-right: 34px !important;
    background: #fff url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23495057' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='18' rx='2'/><path d='M16 2v4M8 2v4M3 10h18'/></svg>") no-repeat right 10px center !important;
}
/* WDateEdit popup calendar (Wt default markup: .Wt-cal table.days, day cells td > div). */
.Wt-datepicker {
    background: #fff !important;
    border: 1px solid var(--gray-300) !important;
    border-radius: var(--radius-lg) !important;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15) !important;
    padding: 10px !important;
}
.Wt-datepicker .Wt-cal table.days {
    width: 266px !important;
    border: 0 !important;
    border-collapse: separate !important;
    border-spacing: 2px !important;
    background: transparent !important;
    font-size: 13px !important;
    line-height: 1.2 !important;
}
.Wt-datepicker .Wt-cal th,
.Wt-datepicker .Wt-cal td {
    width: auto !important;
    padding: 0 !important;
    border: 0 !important;
    background: transparent !important;
    text-align: center !important;
    vertical-align: middle !important;
}
.Wt-datepicker .Wt-cal th.caption {
    padding-bottom: 6px !important;
    color: var(--gray-700) !important;
    font-weight: 600 !important;
}
.Wt-datepicker .Wt-cal th:not(.caption) {
    height: 24px;
    color: var(--gray-500) !important;
    font-size: 11px !important;
    font-weight: 600 !important;
}
.Wt-datepicker .Wt-cal th.caption select {
    margin: 0 !important;
    padding: 3px 6px !important;
    border: 1px solid var(--gray-300) !important;
    border-radius: var(--radius-sm) !important;
    background: #fff !important;
    font-size: 13px !important;
    cursor: pointer;
}
.Wt-datepicker .Wt-cal-year span {
    padding: 3px 4px;
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.Wt-datepicker .Wt-cal-year span:hover { background: var(--gray-100) !important; }
.Wt-datepicker .Wt-cal-navbutton {
    display: flex !important;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    margin: 0 auto !important;
    border-radius: 50% !important;
    background: transparent !important;
    color: var(--gray-700) !important;
    font-size: 16px;
    cursor: pointer;
}
.Wt-datepicker .Wt-cal-navbutton:hover { background: var(--gray-200) !important; }
.Wt-datepicker .Wt-cal td > div {
    width: 34px;
    height: 34px;
    margin: 0 auto;
    line-height: 34px;
    border-radius: 50%;
    color: #212529;
    cursor: pointer;
}
.Wt-datepicker .Wt-cal td > div:hover { background: var(--primary-light) !important; }
.Wt-datepicker .Wt-cal td > div.Wt-cal-oom { color: var(--gray-500) !important; }
.Wt-datepicker .Wt-cal td > div.Wt-cal-oor {
    color: var(--gray-300) !important;
    background: transparent !important;
    cursor: default !important;
}
.Wt-datepicker .Wt-cal td > div.Wt-cal-now {
    box-shadow: inset 0 0 0 1px var(--primary);
    background: transparent !important;
    color: var(--primary) !important;
    font-weight: 700;
}
.Wt-datepicker .Wt-cal td > div.Wt-cal-sel {
    background: var(--primary) !important;
    color: #fff !important;
    font-weight: 700;
}
/* Inline add-address form reads as a distinct card. */
.Wt-dialog.send-order-dialog .checkout-address-form {
    background: #f6f7f9 !important;
    border: 1px solid var(--border-color, #e2e6ea) !important;
    border-radius: 10px !important;
    padding: 16px !important;
    margin-top: 14px !important;
}
/* Order e-mail recipients: read-only To/CC rows plus the own-company copy checkbox. */
.Wt-dialog.send-order-dialog .send-order-mail-recipients {
    display: block !important;
    background: #f6f7f9 !important;
    border: 1px solid var(--border-color, #e2e6ea) !important;
    border-radius: 10px !important;
    padding: 12px 14px !important;
    margin-top: 14px !important;
}
.Wt-dialog.send-order-dialog .send-order-mail-row {
    display: flex !important;
    align-items: baseline;
    gap: 8px;
    font-size: calc(13px * var(--font-scale));
    line-height: 1.45;
}
.Wt-dialog.send-order-dialog .send-order-mail-key {
    flex: 0 0 auto;
    min-width: 84px;
    font-weight: 600;
    color: var(--gray-700);
}
.Wt-dialog.send-order-dialog .send-order-mail-value {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--gray-800);
    overflow-wrap: anywhere;
}
.Wt-dialog.send-order-dialog .send-order-mail-copy {
    display: flex !important;
    align-items: flex-start !important;
    gap: 8px !important;
    margin: 10px 0 0 !important;
    font-size: calc(13px * var(--font-scale));
    overflow-wrap: anywhere;
    cursor: pointer !important;
}
.Wt-dialog.send-order-dialog .send-order-mail-copy input {
    flex: 0 0 auto !important;
    margin: 3px 0 0 !important;
}
/* Full-width footer, pinned to the bottom of the scroll area so the action
   buttons stay reachable however tall the form grows. */
.Wt-dialog.send-order-dialog .checkout-dialog-buttons {
    position: sticky !important;
    bottom: 0 !important;
    display: flex !important;
    justify-content: flex-end !important;
    gap: 10px !important;
    margin: 16px -22px 0 !important;
    padding: 14px 22px !important;
    background: var(--white, #fff) !important;
    border-top: 1px solid var(--border-color, #e2e6ea) !important;
    z-index: 3 !important;
}
@media only screen and (max-width: 820px) {
    body div.Wt-dialog.send-order-dialog,
    .Wt-dialog.send-order-dialog {
        width: min(96vw, 640px) !important;
    }
    .Wt-dialog.send-order-dialog .send-order-columns {
        grid-template-columns: 1fr !important;
        gap: 20px !important;
    }
    .Wt-dialog.send-order-dialog .send-order-products-column .checkout-items {
        max-height: min(30dvh, 220px) !important;
    }
}

/* ============================================================
   PDF export dialog — mobile layout contract.
   Placed last so it wins over the generic mobile dialog rules.

   Wt renders this dialog as .Wt-dialog > .dialog-layout >
   (.titlebar, .body, .footer). The generic mobile block targets
   .Wt-dialog-contents / .contents and .Wt-dialog-footer, which this
   Wt version does not emit, so .dialog-layout keeps flex:0 1 auto /
   min-height:auto, grows to its content past the dialog's
   max-height, and the .Wt-dialog overflow:hidden clips the footer
   away — the wizard's Back/Next/Generate/Close buttons end up
   off-screen. flex:1 + min-height:0 on the wrapper makes .body the
   real scroll port and keeps the footer pinned inside the card.
   ============================================================ */
@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {
    body div.Wt-dialog.pdf-export-dialog,
    .Wt-dialog.pdf-export-dialog {
        width: 96vw !important;
        max-width: 96vw !important;
        height: auto !important;
        /* min-height MUST be reset: min-height beats max-height and would push
           the card past the viewport again. */
        min-height: 0 !important;
        max-height: 92dvh !important;
    }

    .Wt-dialog.pdf-export-dialog > .dialog-layout {
        display: flex !important;
        flex: 1 1 auto !important;
        flex-direction: column !important;
        width: 100% !important;
        max-width: 100% !important;
        min-height: 0 !important;
        max-height: 100% !important;
        overflow: hidden !important;
        box-sizing: border-box !important;
    }

    .Wt-dialog.pdf-export-dialog > .dialog-layout > .titlebar {
        flex: 0 0 auto !important;
    }

    /* The scroll owner. */
    .Wt-dialog.pdf-export-dialog > .dialog-layout > .body {
        flex: 1 1 auto !important;
        min-height: 0 !important;
        height: auto !important;
        max-height: none !important;
        overflow-y: auto !important;
        overflow-x: hidden !important;
        /* Step pages carry their own 16px padding; a second one here would
           halve the usable width. */
        padding: 0 !important;
        -webkit-overflow-scrolling: touch;
    }

    /* Footer carries inline overflow:hidden, which clips the wrapped button
       rows; reset it and lay the buttons out as a wrapping flex row. */
    .Wt-dialog.pdf-export-dialog > .dialog-layout > .footer {
        flex: 0 0 auto !important;
        overflow: visible !important;
        display: flex !important;
        flex-wrap: wrap !important;
        align-items: center !important;
        justify-content: flex-end !important;
        gap: 8px !important;
        padding: 10px 12px !important;
        box-sizing: border-box !important;
    }

    .Wt-dialog.pdf-export-dialog > .dialog-layout > .footer .pdf-btn {
        flex: 1 1 auto !important;
        min-width: 92px !important;
        height: 36px !important;
        margin: 0 !important;
    }

    /* Progress bar and download link each take their own row. */
    .Wt-dialog.pdf-export-dialog > .dialog-layout > .footer .pdf-progress {
        flex: 1 1 100% !important;
        width: auto !important;
        margin: 0 !important;
    }
}

/* Phone landscape: shrink the white nav + green assembly bar so the
   SVG/BOM panel below keeps most of the short viewport height. The
   assembly bar's measured height still feeds --header-height via JS,
   so machine-page-layout's reservation only needs to roughly match. */
@media (orientation: landscape) and (max-height: 600px) {
    .nav-container {
        padding: 2px 12px;
    }

    .nav-logo-img {
        height: 24px;
        max-height: 24px;
    }

    .assembly-bar,
    .assembly-bar-top {
        min-height: 30px;
        padding-top: 2px;
        padding-bottom: 2px;
    }

    .machine-page-layout {
        height: calc(100vh - 78px);
    }

    /* Short landscape (rotated phone): split the shrunk center column
       50/50 between SVG and BOM so BOM keeps a usable, internally
       scrolling half instead of being squeezed by a vh-relative
       flex-basis. Not !important: still loses to the drag-resize inline
       style and to the collapsed/expanded/full-list-mode toggle classes. */
    .machine-page-layout .center-content-area {
        display: flex;
        flex-direction: column;
        min-height: 0;
    }

    .machine-page-layout .viewer-wrapper {
        flex: 1 1 50%;
        min-height: 0;
    }

    .machine-page-layout .bom-wrapper {
        flex: 1 1 50%;
        min-height: 0;
        overflow-y: auto;
    }
}

/* ============================================================
   MOBILE LAYOUT — nav row, assembly bar, footer.
   Declared late because this stylesheet resolves equal-specificity
   ties by file order. Keep above the dialog contract block.
   ============================================================ */
@media (max-width: 768px) {

    /* The nav is a CSS grid on phones, and the right-host is set to span
       every column, which forces the selector/search/cart onto their own
       row. Three explicit columns put logo, trio and account on one line.
       Logo dimensions are deliberately NOT touched here: the image is
       capped by max-width/max-height elsewhere, so setting an explicit
       height against that cap distorts its ratio. */
    .nav-container {
        grid-template-columns: auto minmax(0, 1fr) auto !important;
        gap: 4px !important;
        padding-left: 6px !important;
        padding-right: 6px !important;
    }

    .nav-logo-link {
        grid-column: 1 !important;
    }

    .nav-right-host {
        grid-column: 2 !important;
        width: auto !important;
        min-width: 0 !important;
        margin-left: auto !important;
        justify-content: flex-end !important;
        flex-wrap: nowrap !important;
        gap: 4px !important;
    }

    .nav-right-host .nav-icon-btn {
        width: 30px !important;
        height: 30px !important;
        min-width: 30px !important;
        flex: 0 0 30px !important;
    }

    /* Machine selector collapses to its dropdown indicator; the native
       picker still lists the full option names on tap. Company switch is
       left alone — it carries the only label on non-machine routes. */
    .nav-right-host .machine-dropdown {
        flex: 0 0 40px !important;
        width: 40px !important;
        min-width: 40px !important;
        max-width: 40px !important;
        padding: 0 1px !important;
        color: transparent !important;
    }

    /* Options keep their own colour so the picker stays readable. */
    .nav-right-host .machine-dropdown option {
        color: var(--black) !important;
    }

    /* Account sits in the third column; the name stays visible. */
    .user-dropdown-btn {
        grid-column: 3 !important;
        justify-self: end !important;
        min-width: 0 !important;
        margin-left: 0 !important;
        padding: 0 6px !important;
        gap: 3px !important;
    }

    /* Name shrinks first when the row is tight, down to a short prefix. */
    .user-dropdown-name {
        max-width: 60px !important;
        min-width: 0 !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
        white-space: nowrap !important;
    }

    /* Part-info drawer: 100vh is the large viewport on mobile browsers, so
       the panel bottom (and the tail of the spec list) sits under the
       browser toolbars. dvh tracks the visible area. */
    .part-info-sidebar {
        height: 100dvh !important;
        max-height: 100dvh !important;
    }

    /* Assembly bar: the name is the useful label, so it takes the
       leftover width while the surrounding controls shrink. */
    .assembly-bar-top {
        padding: 3px 6px !important;
        gap: 6px !important;
    }

    .assembly-bar-left {
        gap: 6px !important;
    }

    .assembly-bar-name {
        font-size: calc(13px * var(--font-scale)) !important;
        flex: 1 1 auto !important;
        min-width: 0 !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
    }

    .assembly-bar-code {
        font-size: calc(11px * var(--font-scale)) !important;
        letter-spacing: 0 !important;
        flex: 0 1 auto !important;
        min-width: 0 !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
    }

    .assembly-bar-version select,
    .assembly-bar-dropdown {
        font-size: calc(11px * var(--font-scale)) !important;
        height: 26px !important;
        padding: 0 4px !important;
    }

    /* Footer at half its previous height. */
    .footer,
    .spareparts-page .footer {
        padding: 3px 8px !important;
        margin: 3px 6px !important;
        font-size: calc(10px * var(--font-scale)) !important;
        border-radius: 6px !important;
    }

    .footer .font-size-btn {
        height: 24px !important;
        min-width: 26px !important;
        padding: 0 5px !important;
        font-size: calc(11px * var(--font-scale)) !important;
    }
}

/* ── Maintenance component config: locked checkbox groups ────────────
   One checkbox per allowed value of maintenance_field_options. Wraps so a
   long vocabulary does not stretch the dialog. */
.flag-check-group {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 16px;
    width: 100%;
}

.flag-check-item {
    display: inline-flex;
    align-items: center;
}

.flag-check-item input[type="checkbox"] {
    margin-right: 6px;
}

/* Value stored in the row but missing from the vocabulary. Kept selectable so
   legacy data survives a save; marked so the operator can see it is stale.
   Colour is a dark amber, not var(--warning): #ffc107 fails the 4.5:1 text
   contrast the rest of the app is held to. The glyph carries the meaning on
   its own so the mark does not rely on colour alone. */
.flag-check-unknown label,
.flag-check-unknown span {
    color: #856404;
    font-style: italic;
}

.flag-check-unknown::after {
    content: "\26a0";           /* warning sign */
    margin-left: 4px;
    color: #856404;
}

/* ── Maintenance managed-vocabulary panel (secondary, collapsed) ───── */
.vocab-panel {
    margin-top: 12px;
    opacity: 0.92;
}

.vocab-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
    padding: 6px 0;
    border-bottom: 1px solid var(--gray-200, #e9ecef);
}

.vocab-label {
    min-width: 180px;
    font-weight: 600;
    color: var(--gray-700, #495057);
}

.vocab-values {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    flex: 1 1 auto;
}

.vocab-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 8px;
    border: 1px solid var(--gray-300, #dee2e6);
    border-radius: 12px;
    background: var(--gray-100, #f8f9fa);
    font-size: var(--font-size-sm);
}

button.vocab-chip-remove,
.vocab-chip-remove {
    padding: 0 6px !important;
    min-width: 0 !important;
    height: auto !important;
    border: none !important;
    background: transparent !important;
    color: var(--danger, #c0392b) !important;
    font-size: var(--font-size-sm) !important;
    line-height: 1.2 !important;
    box-shadow: none !important;
}

/* ============================================================
   ASSEMBLY-SCOPED PART DETAILS
   Marks content that belongs to one assembly instead of to the
   part number everywhere. Amber is the scope colour throughout.
   ============================================================ */

/* BOM row icon whose detail comes from the assembly-scoped row. */
.part-detail-icon-scoped {
    color: var(--warning, #b8860b);
}

/* Part-detail view showing an assembly-scoped drawing. */
.part-detail-scoped {
    border-left: 3px solid var(--warning, #b8860b);
}

/* Details tab while the assembly-scoped record is being edited. */
.part-detail-scope-banner {
    border-left: 3px solid var(--warning, #b8860b);
    background: rgba(184, 134, 11, 0.04);
}

/* Card-head marker repeating the active scope. */
.part-detail-scope-badge {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 8px;
    border-radius: 10px;
    background: rgba(184, 134, 11, 0.14);
    color: var(--warning, #b8860b);
    font-size: var(--font-size-sm);
    line-height: 1.6;
    white-space: nowrap;
}

/* Scoped record has a parts list but no drawing: nothing is shown. */
.part-detail-scope-warning {
    margin-top: 6px;
    color: var(--warning, #b8860b);
    font-size: var(--font-size-sm);
    line-height: 1.4;
}

/* Explains why the content cards are disabled. */
.part-detail-scope-suppressed-hint {
    margin-top: 6px;
    color: var(--danger, #c0392b);
    font-size: var(--font-size-sm);
    line-height: 1.4;
}

/* ============================================================
   Version compare dialog (BOM diff between two catalog versions)

   Wt renders .Wt-dialog > .dialog-layout > (.titlebar, .body, .footer).
   .dialog-layout carries inline `display:flex; flex-flow:column` but no flex
   sizing, so it grows to its content and .Wt-dialog just clips the overflow --
   no scrollbar is ever generated. flex:1 + min-height:0 on the wrapper plus a
   bounded max-height is what makes .body a real scroll port.
   ============================================================ */
.version-compare-dialog {
    max-height: 86vh;
}

.Wt-dialog.version-compare-dialog .dialog-layout {
    display: flex !important;
    flex: 1 1 auto !important;
    flex-direction: column !important;
    min-height: 0 !important;
    max-height: 86vh !important;
    overflow: hidden !important;
}

/* The scroll owner. Deliberately a BLOCK box: as a flex column its children
   shrink to fit instead of overflowing, so no scrollbar appears and the lower
   sections become unreachable. */
.Wt-dialog.version-compare-dialog .body {
    display: block !important;
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: auto !important;
    max-height: none !important;
    overflow-x: hidden !important;
    overflow-y: auto !important;
    padding: 0 !important;
}

.Wt-dialog.version-compare-dialog .footer {
    flex: 0 0 auto !important;
}

.version-compare-content {
    display: block;
    width: 100%;
    padding: var(--spacing-lg);
    box-sizing: border-box;
}

/* Stays visible while the sections below scroll. */
.version-compare-header {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--white);
    padding-bottom: 10px;
    margin-bottom: 4px;
}

/* Picker strip: the two version selects read as one "from -> to" control,
   centered above the results. */
.version-compare-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    align-items: flex-end;
    justify-content: center;
    padding: 12px 14px;
    background: var(--gray-100);
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-lg);
}

.version-compare-picker-field {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.version-compare-picker-label {
    color: var(--gray-600);
    font-size: var(--font-size-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.version-compare-picker-arrow {
    align-self: flex-end;
    padding-bottom: 7px;
    color: var(--gray-500);
    font-size: var(--font-size-lg);
    font-weight: 700;
    line-height: 1;
}

.version-compare-select {
    min-width: 170px;
    height: 34px;
    padding: 0 10px;
    box-sizing: border-box;
    background: var(--white);
    color: var(--gray-800);
    border: 1px solid var(--gray-400);
    border-radius: var(--radius-md);
    font-family: var(--font-family);
    font-size: var(--font-size-base);
    font-weight: 600;
    cursor: pointer;
}

.version-compare-select:hover {
    border-color: var(--gray-600);
}

.version-compare-select:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(25, 135, 84, 0.18);
}

.version-compare-summary {
    display: block;
    margin-top: 12px;
    text-align: center;
    color: var(--gray-700);
    font-size: var(--font-size-base);
    font-weight: 700;
}

.version-compare-results {
    display: block;
}

.version-compare-section {
    border: 1px solid var(--gray-200);
    border-radius: 6px;
    border-left-width: 4px;
    overflow: hidden;
    margin-bottom: 16px;
}

.version-compare-section:last-child {
    margin-bottom: 0;
}

.version-compare-added   { border-left-color: var(--success, #198754); }
.version-compare-removed { border-left-color: var(--danger, #c0392b); }
.version-compare-changed { border-left-color: var(--warning, #b8860b); }

.version-compare-section-title {
    display: block;
    padding: 8px 12px;
    background: var(--gray-100);
    color: var(--gray-700);
    font-weight: 700;
}

.version-compare-empty {
    display: block;
    padding: 10px 12px;
    color: var(--gray-500);
    font-size: var(--font-size-sm);
}

.version-compare-scroll {
    overflow-x: auto;
}

.version-compare-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}

.version-compare-table th,
.version-compare-table td {
    padding: 8px 10px;
    border-bottom: 1px solid var(--gray-200);
    vertical-align: middle;
}

.version-compare-table th {
    background: var(--gray-100);
    color: var(--gray-600);
    font-weight: 700;
    text-align: left;
}

.version-compare-table th:nth-child(1) { width: 54px; text-align: center; }
.version-compare-table th:nth-child(2) { width: 22%; }
.version-compare-table th:nth-child(3) { width: auto; }
.version-compare-table th:nth-child(4) { width: 90px; }
.version-compare-table th:nth-child(5) { width: 90px; text-align: center; }

.version-compare-table td:nth-child(1),
.version-compare-table td:nth-child(5) {
    text-align: center;
}

.version-compare-image-cell {
    padding-left: 4px !important;
    padding-right: 4px !important;
}

.version-compare-image {
    width: 34px;
    height: 34px;
    object-fit: contain;
    border-radius: 3px;
    background: #f8f9fa;
    vertical-align: middle;
}

.version-compare-number {
    font-weight: 600;
    word-break: break-all;
}

.version-compare-qty {
    white-space: nowrap;
}

/* Version compare — drawing panes. */
.version-compare-dialog {
    max-width: min(1280px, 94vw);
}

.version-compare-drawings {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 16px;
    min-height: 0;
}

.version-compare-drawing-pane {
    flex: 1 1 50%;
    min-width: 0;
    display: flex;
    flex-direction: column;
    height: 340px;
    border: 1px solid var(--gray-200);
    border-radius: 6px;
    overflow: hidden;
    background: var(--white);
}

.version-compare-drawing-caption {
    display: block;
    flex: 0 0 auto;
    padding: 6px 10px;
    background: var(--gray-100);
    color: var(--gray-700);
    font-size: var(--font-size-sm);
    font-weight: 700;
}

/* The viewer subtree is a flex item chain; each level defaults to
   min-width:auto and would otherwise refuse to shrink below its content,
   pushing the pane past its 50% basis and overflowing the dialog. Scoped to
   this dialog so the main page's viewer sizing is untouched. */
.version-compare-drawing-pane .viewer-container,
.version-compare-drawing-pane .viewer-stack,
.version-compare-drawing-pane .svg-viewer,
.version-compare-drawing-pane .svg-viewer-wrapper {
    min-width: 0 !important;
    max-width: 100% !important;
}

.version-compare-drawing-empty {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    justify-content: center;
    color: var(--gray-500);
    font-style: italic;
}

.version-compare-legend {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 18px;
    font-size: var(--font-size-sm);
    color: var(--gray-600);
}

.version-compare-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* Shape carries the same information as the colour. */
.version-compare-legend-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 3px;
    border: 2px solid;
    font-weight: 700;
    line-height: 1;
}

.version-compare-legend-added .version-compare-legend-badge {
    background: rgba(25, 135, 84, 0.42);
    border-color: #146c43;
    border-style: solid;
    color: #146c43;
}

.version-compare-legend-removed .version-compare-legend-badge {
    background: rgba(192, 57, 43, 0.40);
    border-color: #a02b1e;
    border-style: dashed;
    color: #a02b1e;
}

.version-compare-legend-changed .version-compare-legend-badge {
    background: rgba(184, 134, 11, 0.40);
    border-color: #8a6407;
    border-style: dotted;
    color: #8a6407;
}

.version-compare-legend-note {
    flex: 1 1 100%;
    color: var(--gray-500);
    font-style: italic;
}

/* Reveal button is mobile-only; on desktop the drawings are always built. */
.version-compare-drawings-toggle.Wt-btn {
    display: none !important;
}

/* Version compare, intermediate widths: past the mobile breakpoint the two
   drawings are still side by side, but under ~1150px each pane is too narrow
   to read a machine drawing. Stack them so each gets the full dialog width.
   Declared before the MOBILE DIALOG CONTRACT block, which still wins below
   768px and hides them behind the reveal button there. */
@media only screen and (max-width: 1150px) {
    .version-compare-drawings {
        flex-direction: column;
    }

    .version-compare-drawing-pane {
        flex: 1 1 auto;
        width: 100%;
        height: 380px;
    }

    /* Five fixed columns cannot fit; let them size to content and scroll. */
    .version-compare-table {
        table-layout: auto;
    }

    .version-compare-table th,
    .version-compare-table td {
        width: auto;
        min-width: 0;
        white-space: normal;
        word-break: break-word;
    }
}

/* Replaced parts: card list. Declared before the MOBILE DIALOG CONTRACT block. */
.replaced-card {
    background: var(--white);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-lg);
    padding: 8px 12px;
    margin-bottom: 6px;
}

.replaced-card.is-completed {
    background: var(--gray-100);
    opacity: 0.85;
}

.replaced-card-head {
    display: flex;
    align-items: center;
    gap: 10px;
}

.replaced-card-toggle {
    flex: 0 0 auto;
    width: 1.2em;
    text-align: center;
    color: var(--gray-600);
}

.replaced-card-thumb {
    flex: 0 0 48px;
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--gray-100);
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

.replaced-card-thumb img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.replaced-card-artikel {
    flex: 0 0 auto;
    min-width: 7em;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.replaced-card-name {
    flex: 1 1 0;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.replaced-card-badge {
    flex: 0 0 130px;
    box-sizing: border-box;
    padding: 1px 10px;
    border-radius: 999px;
    background: var(--primary-light);
    color: var(--primary-dark);
    font-size: var(--font-size-sm);
    font-weight: 700;
    text-align: center;
    white-space: nowrap;
}

.replaced-card-stock {
    flex: 0 0 100px;
    box-sizing: border-box;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 1px 10px;
    border-radius: 999px;
    background: var(--gray-200);
    color: var(--gray-700);
    font-size: var(--font-size-sm);
    font-weight: 700;
    text-align: center;
    white-space: nowrap;
}

.replaced-slot-check {
    flex: 0 0 90px;
    width: 90px;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}

.replaced-card-right {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
}

/* Sticky list header needs every ancestor up to the real scroller to be non-scrolling. */
.settings-tab-content.replaced-tab {
    overflow: visible !important;
}

.ctabs-stack:has(.replaced-tab) {
    overflow: visible !important;
}

.replaced-card-list-head {
    position: sticky;
    top: var(--replaced-sticky-top, 0);
    z-index: 1;
    background: var(--white);
    display: flex;
    align-items: flex-end;
    gap: 10px;
    padding: 6px 13px 4px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--gray-300);
    font-size: var(--font-size-sm);
    font-weight: 700;
    color: var(--gray-600);
    line-height: 1.2;
}

.replaced-card-list-head .replaced-card-thumb {
    height: 0;
    border: 0;
    background: none;
}

.replaced-card-badge:empty,
.replaced-card-stock:empty {
    background: none;
    padding: 0;
}

.replaced-card-badge-head {
    flex: 0 0 130px;
}

.replaced-card-stock-head {
    flex: 0 0 100px;
}

.replaced-card-badge-head,
.replaced-card-stock-head {
    text-align: center;
    white-space: nowrap;
}

.replaced-card-meta {
    flex: 0 0 auto;
    font-size: var(--font-size-sm);
    color: var(--gray-600);
}

.replaced-card-body {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--gray-200);
}

.replaced-card-grid {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 4px 16px;
    font-size: var(--font-size-sm);
}

.replaced-card-label {
    color: var(--gray-600);
    font-weight: 600;
}

.replaced-card-value {
    min-width: 0;
    overflow-wrap: anywhere;
}

.replaced-card-asm-table {
    width: 100%;
}

@media only screen and (max-width: 768px) {
    .replaced-filters select.edit-input {
        flex: 1 1 100%;
    }

    .replaced-card-head {
        flex-wrap: wrap;
        gap: 6px 10px;
    }

    .replaced-card-name {
        flex: 1 1 100%;
        white-space: normal;
    }

    .replaced-card-artikel {
        min-width: 0;
    }

    .replaced-slot-check {
        flex-basis: 56px;
        width: 56px;
    }

    .replaced-card-right {
        flex: 1 1 100%;
        justify-content: flex-start;
    }

    .replaced-card-list-head {
        flex-wrap: nowrap;
    }

    .replaced-card-list-head > :not(.replaced-slot-check) {
        display: none;
    }
}

/* "Already in cart" markers (informational only). */
.bom-table td.bom-cart-col {
    position: relative;
}

/* Absolutely positioned left of the checkbox so the checkbox column stays aligned. */
.bom-cart-col .bom-in-cart-icon {
    position: absolute;
    left: 2px;
    top: 50%;
    transform: translateY(-50%);
    display: inline-block;
    width: 14px;
    height: 14px;
    background-color: var(--success);
    -webkit-mask: url('../files/essentials/cart.svg') center / contain no-repeat;
    mask: url('../files/essentials/cart.svg') center / contain no-repeat;
    cursor: pointer;
}

.bom-bulk-add-table .bulk-add-in-cart-note {
    display: block;
    margin-top: 2px;
    font-size: 0.8em;
    color: var(--success);
}

.part-info-in-cart {
    display: block;
    margin-top: 4px;
    font-size: 0.82em;
    color: var(--success);
}

/* "Already in cart" info dialog. */
.Wt-dialog.bom-in-cart-dialog {
    width: min(380px, 92vw) !important;
}

.bom-in-cart-dialog .bom-in-cart-content {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.bom-in-cart-dialog .bom-in-cart-msg {
    font-weight: 600;
}

.bom-in-cart-dialog .bom-in-cart-name {
    color: var(--text-muted, #666);
}

.bom-in-cart-dialog .dialog-buttons {
    display: flex;
    justify-content: flex-end;
    margin-top: 10px;
}

/* Order details: grouped / single-list switch and per-line usage note. */
.order-items-box .order-view-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 4px 0 8px 0;
    font-size: 0.9em;
}

.order-items-table .order-item-usage {
    font-size: 0.85em;
    color: #777;
}

/* Maintenance "Request Change" dialog (config_change_request.cpp). Elements
   toggled with hide()/show() are styled here, not inline.
   CSS centering keeps the dialog centred while checked fields expand it; the
   body scrolls once the dialog reaches the height cap. The mobile contract
   block overrides the position on phones. */
body div.Wt-dialog.config-change-request-dialog {
    position: fixed !important;
    top: 50% !important;
    left: 50% !important;
    right: auto !important;
    bottom: auto !important;
    margin: 0 !important;
    max-width: 96vw !important;
    transform: translate(-50%, -50%) !important;
}

.Wt-dialog.config-change-request-dialog .config-change-request-content {
    max-height: calc(90vh - 140px) !important;
    max-height: calc(90dvh - 140px) !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
}

.config-change-request-dialog .ccr-fix {
    margin-top: 6px;
}

.config-change-request-dialog .ccr-fix-caption {
    font-size: 0.85em;
    color: #6c757d;
    margin-bottom: 2px;
}

.config-change-request-dialog .ccr-fix-input,
.config-change-request-dialog .ccr-notes {
    width: 100%;
    box-sizing: border-box;
}

.config-change-request-dialog .ccr-notes {
    display: block;
    margin-top: 14px;
}

.config-change-request-dialog .ccr-status {
    margin-top: 10px;
    font-size: 0.9em;
    color: #c0392b;
}

/* ============================================================
   MOBILE DIALOG CONTRACT — authoritative, KEEP LAST IN FILE.
   Earlier mobile dialog rules sit above unconditional base rules
   that tie on specificity and win purely by file order. Every
   declaration here is !important and stays last so it cannot be
   undone the same way. Add new dialog mobile rules to this block.
   ============================================================ */
@media only screen and (max-width: 768px), (hover: none) and (pointer: coarse) {

    /* Wt closes a dialog by writing inline display:none (no !important).
       The mobile `.Wt-dialog { display:flex !important }` rules would beat
       it and keep closed dialogs visible; this restores the native close. */
    .Wt-dialog[style*="display: none"],
    .Wt-dialog[style*="display:none"] {
        display: none !important;
    }

    /* Dialog internals fill the CSS-driven root width. Wt writes an inline
       px width on the root from setWidth(); once the media query narrows the
       root, inner boxes keep the old width and leave a gap on the right.
       send-order and pdf-export size their own layout. */
    .Wt-dialog:not(.send-order-dialog):not(.pdf-export-dialog) > .dialog-layout,
    .Wt-dialog:not(.send-order-dialog):not(.pdf-export-dialog) > .Wt-dialog-contents,
    .Wt-dialog:not(.send-order-dialog):not(.pdf-export-dialog) > .contents,
    .Wt-dialog:not(.send-order-dialog):not(.pdf-export-dialog) .body,
    .Wt-dialog:not(.send-order-dialog):not(.pdf-export-dialog) .Wt-dialog-body {
        width: 100% !important;
        box-sizing: border-box !important;
    }

    .cart-dialog-content,
    .dialog-input-full,
    .dialog-buttons {
        width: 100% !important;
        box-sizing: border-box !important;
    }

    /* BOM bulk add-to-cart: the base th:nth-child pixel widths sit later in
       the file at equal specificity and beat the earlier mobile reset, so the
       columns are re-flattened here and residual overflow stays reachable. */
    .bom-bulk-add-dialog .bom-bulk-add-table {
        table-layout: auto !important;
        width: 100% !important;
    }

    .bom-bulk-add-dialog .bom-bulk-add-table th,
    .bom-bulk-add-dialog .bom-bulk-add-table td,
    .bom-bulk-add-dialog .bom-bulk-add-table th:nth-child(1),
    .bom-bulk-add-dialog .bom-bulk-add-table th:nth-child(2),
    .bom-bulk-add-dialog .bom-bulk-add-table th:nth-child(3),
    .bom-bulk-add-dialog .bom-bulk-add-table th:nth-child(4),
    .bom-bulk-add-dialog .bom-bulk-add-table th:nth-child(5) {
        width: auto !important;
        min-width: 0 !important;
        white-space: normal !important;
        word-break: break-word !important;
    }

    .bom-bulk-add-dialog .bom-bulk-add-image-cell,
    .bom-bulk-add-dialog .bom-bulk-add-table th:nth-child(1) {
        width: 36px !important;
        min-width: 36px !important;
    }

    .bom-bulk-add-dialog .bom-bulk-add-qty-cell {
        white-space: normal !important;
    }

    .bom-bulk-add-dialog .bom-bulk-add-scroll {
        overflow-x: auto !important;
    }

    /* Order details: the generic `.Wt-dialog .body { overflow-x: hidden }`
       clips the wide item tables. Restore horizontal scrolling and keep the
       line-item columns on one line so they stay readable while scrolling. */
    .Wt-dialog.order-details-dialog .order-details-content {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    .order-details-dialog .order-items-table {
        min-width: 560px !important;
    }

    .order-details-dialog .order-items-table th,
    .order-details-dialog .order-items-table td {
        white-space: nowrap !important;
    }

    /* Cart detail parts ("+ Parts"): a 6-column table cannot use the generic
       460px cap, and its fixed pixel columns total more than the dialog. */
    .cart-detail-parts-dialog {
        width: 96vw !important;
        max-width: 96vw !important;
        max-height: 92dvh !important;
    }

    .cart-detail-parts-dialog .cart-detail-parts-table {
        table-layout: auto !important;
        width: 100% !important;
    }

    .cart-detail-parts-dialog .cart-detail-parts-table th,
    .cart-detail-parts-dialog .cart-detail-parts-table td {
        width: auto !important;
        min-width: 0 !important;
        white-space: normal !important;
        word-break: break-word !important;
    }

    .cart-detail-parts-dialog .cart-detail-parts-image-cell {
        width: 40px !important;
        min-width: 40px !important;
    }

    /* Overrides the inline setWidth(60) Wt writes on the quantity input. */
    .cart-detail-parts-dialog .cart-detail-qty-input {
        width: 48px !important;
        min-width: 0 !important;
    }

    .cart-detail-parts-dialog .cart-detail-parts-scroll {
        overflow-x: auto !important;
    }

    /* Wt renders .Wt-dialog > .dialog-layout > (.titlebar, .body).
       .dialog-layout has no flex sizing, so it grows past the dialog's
       max-height and the overflow is clipped by .Wt-dialog instead of
       scrolling. flex:1 + min-height:0 bounds it so the inner
       .cart-detail-parts-scroll becomes a real scroll port (same fix as
       send-order-dialog / bom-bulk-add-dialog). Extra selectors are
       Wt-version fallbacks. */
    .Wt-dialog.cart-detail-parts-dialog .dialog-layout,
    .Wt-dialog.cart-detail-parts-dialog .Wt-dialog-contents,
    .Wt-dialog.cart-detail-parts-dialog .contents {
        display: flex !important;
        flex: 1 1 auto !important;
        flex-direction: column !important;
        min-height: 0 !important;
        max-height: none !important;
        overflow: hidden !important;
    }

    /* Action row stays visible below the scrolling table. */
    .cart-detail-parts-dialog .dialog-buttons {
        flex-shrink: 0;
    }

    /* "See assemblies": the class is applied in C++ but had no rules. */
    .cart-assembly-mobile-dialog {
        width: min(92vw, 360px) !important;
    }

    .cart-assembly-mobile-dialog .assembly-cell-line {
        min-height: 40px !important;
        display: flex !important;
        align-items: center !important;
        padding: 8px 10px !important;
    }

    /* Wide content that the generic 460px cap crushes. */
    .guest-checkout-dialog,
    .artikel-import-dialog,
    .multi-csv-import-dialog,
    .conversion-import-dialog {
        width: 96vw !important;
        max-width: 96vw !important;
        max-height: 92dvh !important;
    }

    /* PDF viewer: title bar already wraps via its own inline style
       (pdffileviewer.cpp), but the search input has an inline width:140px
       that needs to shrink so it fits alongside 4 buttons on a phone. */
    .pdf-file-viewer .pdf-viewer-bar {
        flex-wrap: wrap !important;
    }

    .pdf-file-viewer .pdf-viewer-search {
        width: auto !important;
        min-width: 0 !important;
        flex: 1 1 120px !important;
    }

    /* Retrofit CSV import preview: the outer container has an inline
       min-width:700px (retrofitcsvimportdialog.cpp) that forces overflow
       even for narrow previews. Its scroll ancestor already sets
       overflow-x:auto inline, so only the min-width needs neutralizing. */
    .retrofit-csv-import-dialog .retrofit-import-preview {
        min-width: 0 !important;
    }

    /* Machine Configuration confirm dialog: label cells use an inline
       width:160px (maintenancepage.cpp) with no class, which leaves almost
       no room for the value column under the generic 460px dialog cap. */
    .machine-config-dialog table td:first-child,
    .config-change-request-dialog table td:first-child {
        width: auto !important;
        min-width: 0 !important;
    }

    /* Order tables: the unconditional min-width:200px + nowrap on
       .order-actions-cell (line ~5114) forces horizontal scroll on every
       phone. Let the cell shrink so its buttons wrap/stack instead. */
    .order-actions-cell {
        min-width: 0 !important;
        white-space: normal !important;
    }

    /* Order tabs: wide order tables scroll inside the tab content. */
    .order-tab-content {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    /* Tree drawer: 100vh is the large viewport on mobile browsers, so the
       drawer bottom sits under the browser toolbars. dvh tracks the visible
       area; browsers without dvh keep the earlier vh rules. */
    .machine-page-layout .panel-left {
        height: 100dvh !important;
        max-height: 100dvh !important;
    }
    .assembly-tree-content {
        max-height: calc(100dvh - 44px - 40px) !important;
        padding-bottom: env(safe-area-inset-bottom);
    }

    /* Tree drawer text: compact size on touch layouts; desktop keeps 12/11px. */
    .assembly-tree-name { font-size: calc(10px * var(--font-scale)) !important; }
    .assembly-tree-code { font-size: calc(9.5px * var(--font-scale)) !important; }

    /* Assembly bar keeps a single row; overflowing pills (machine-number
       selector) are reached by horizontal scroll instead of being clipped
       by .panel-center. */
    .assembly-bar-top {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }

    /* Settings tabs: horizontal scroll as fallback when card-mode cells
       still overflow. Replaces the overflow-x:hidden clip on phones. */
    .settings-tab-content {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    /* Import tables: width floors so their scroll wrappers scroll instead
       of crushing columns. compare-data-table is floored only inside a
       scroll wrapper; unwrapped instances (editassembly compare tab,
       parts-import conflicts) keep their squeeze behavior. */
    .fileimport-table { min-width: 720px !important; }
    .import-tree-table { min-width: 640px !important; }
    .table-scroll-wrapper > .compare-data-table { min-width: 640px !important; }

    /* Affected Wt dialogs use .dialog-layout as the direct wrapper. Keep the
       wrapper bounded so the named body becomes a real scroll port and the
       footer stays inside the visible viewport. */
    body div.Wt-dialog.bom-bulk-add-dialog,
    body div.Wt-dialog.order-details-dialog,
    body div.Wt-dialog.order-export-dialog,
    body div.Wt-dialog.machine-config-dialog,
    body div.Wt-dialog.config-change-request-dialog {
        top: 4vh !important;
        top: 4dvh !important;
        left: 2vw !important;
        right: auto !important;
        bottom: auto !important;
        width: 96vw !important;
        min-width: 0 !important;
        max-width: 96vw !important;
        height: 92vh !important;
        height: 92dvh !important;
        min-height: 0 !important;
        max-height: 92vh !important;
        max-height: 92dvh !important;
        overflow: hidden !important;
        padding-bottom: env(safe-area-inset-bottom) !important;
        box-sizing: border-box !important;
        transform: none !important;
    }

    .Wt-dialog.bom-bulk-add-dialog > .dialog-layout,
    .Wt-dialog.order-details-dialog > .dialog-layout,
    .Wt-dialog.order-export-dialog > .dialog-layout,
    .Wt-dialog.machine-config-dialog > .dialog-layout,
    .Wt-dialog.config-change-request-dialog > .dialog-layout {
        display: flex !important;
        flex: 1 1 auto !important;
        flex-direction: column !important;
        width: 100% !important;
        height: 100% !important;
        min-height: 0 !important;
        max-height: 100% !important;
        overflow: hidden !important;
        box-sizing: border-box !important;
    }

    .Wt-dialog.bom-bulk-add-dialog > .dialog-layout > .titlebar,
    .Wt-dialog.order-details-dialog > .dialog-layout > .titlebar,
    .Wt-dialog.order-export-dialog > .dialog-layout > .titlebar,
    .Wt-dialog.machine-config-dialog > .dialog-layout > .titlebar,
    .Wt-dialog.machine-config-dialog > .dialog-layout > .footer,
    .Wt-dialog.config-change-request-dialog > .dialog-layout > .titlebar,
    .Wt-dialog.config-change-request-dialog > .dialog-layout > .footer {
        flex: 0 0 auto !important;
    }

    .Wt-dialog.bom-bulk-add-dialog .bom-bulk-add-content,
    .Wt-dialog.order-details-dialog .order-details-content,
    .Wt-dialog.order-export-dialog .order-export-dialog-content,
    .Wt-dialog.machine-config-dialog .machine-config-dialog-content,
    .Wt-dialog.config-change-request-dialog .config-change-request-content {
        flex: 1 1 auto !important;
        width: 100% !important;
        height: auto !important;
        min-height: 0 !important;
        max-height: none !important;
        overflow-y: auto !important;
        box-sizing: border-box !important;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
    }

    .Wt-dialog.bom-bulk-add-dialog .bom-bulk-add-content {
        overflow: hidden !important;
    }

    .Wt-dialog.bom-bulk-add-dialog .bom-bulk-add-scroll {
        flex: 1 1 auto !important;
        min-height: 0 !important;
        overflow: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    .Wt-dialog.order-details-dialog .order-details-content {
        overflow-x: hidden !important;
        padding-bottom: calc(12px + env(safe-area-inset-bottom)) !important;
    }

    .Wt-dialog.order-details-dialog .order-items-box {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    .Wt-dialog.order-details-dialog .dialog-buttons,
    .Wt-dialog.order-export-dialog .dialog-buttons {
        position: sticky !important;
        bottom: 0 !important;
        z-index: 2 !important;
        margin-top: 12px !important;
        padding: 10px 0 calc(10px + env(safe-area-inset-bottom)) !important;
        background: var(--white) !important;
        border-top: 1px solid var(--gray-200) !important;
    }

    .Wt-dialog.machine-config-dialog > .dialog-layout > .footer,
    .Wt-dialog.config-change-request-dialog > .dialog-layout > .footer {
        overflow: visible !important;
        padding-bottom: env(safe-area-inset-bottom) !important;
    }

    /* Part price export: action buttons wrap inside the narrowed dialog. */
    .Wt-dialog.part-price-export-dialog .dialog-buttons {
        flex-wrap: wrap !important;
    }

    /* Shopping-cart order tables keep their column floor and scroll only
       inside the selected order tab. */
    .shopping-cart-page .order-tab-stack,
    .shopping-cart-page .order-tab-content {
        min-width: 0 !important;
        max-width: 100% !important;
    }

    .shopping-cart-page .order-tab-content {
        overflow-x: auto !important;
        overflow-y: visible !important;
        touch-action: pan-x pan-y;
    }

    .shopping-cart-page .order-table {
        width: max-content !important;
        min-width: 560px !important;
    }

    /* Spare Parts machine cards keep management and row actions inside the
       card instead of forcing a page-wide horizontal overflow. */
    .settings-admin-content .management-container,
    .settings-admin-content .actions-container,
    .settings-admin-content .sort-container {
        width: 100% !important;
        min-width: 0 !important;
        flex-wrap: wrap !important;
    }

    .settings-admin-content .management-container > button,
    .settings-admin-content .actions-container > button {
        flex: 1 1 110px !important;
        min-width: 0 !important;
        max-width: 100% !important;
    }

    /* Maintenance tables own any residual overflow that cannot be expressed
       by their mobile card layout. */
    .settings-tab-content .maintenance-settings-container,
    .settings-tab-content .table-scroll-wrapper {
        min-width: 0 !important;
        max-width: 100% !important;
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    /* Maintenance Tasks/Parts keep their engine tabs and data tables as two
       explicit horizontal scroll ports. The shared machine-table card mode
       removes the table's intrinsic width, leaving nothing to scroll. */
    .maintenance-settings-tab {
        width: 100% !important;
        min-width: 0 !important;
        max-width: 100% !important;
        overflow-x: hidden !important;
        box-sizing: border-box !important;
    }

    .maintenance-settings-tab .maintenance-settings-container,
    .maintenance-settings-tab .maintenance-settings-container > .Wt-vboxlayout,
    .maintenance-settings-tab .engine-tabset,
    .maintenance-settings-tab .engine-tab-stack,
    .maintenance-settings-tab .engine-tab-stack > div,
    .maintenance-settings-tab .collapsible-panel,
    .maintenance-settings-tab .collapsible-panel-body {
        width: 100% !important;
        min-width: 0 !important;
        max-width: 100% !important;
        box-sizing: border-box !important;
    }

    .maintenance-settings-tab .engine-tabset {
        overflow-x: hidden !important;
    }

    .maintenance-settings-tab .engine-tab-bar {
        display: flex !important;
        width: 100% !important;
        min-width: 0 !important;
        max-width: 100% !important;
        flex-wrap: nowrap !important;
        overflow-x: scroll !important;
        overflow-y: hidden !important;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        touch-action: pan-x;
    }

    .maintenance-settings-tab .engine-tab-bar > button {
        flex: 0 0 auto !important;
    }

    .maintenance-settings-tab .table-scroll-wrapper {
        display: block !important;
        width: 100% !important;
        min-width: 0 !important;
        max-width: 100% !important;
        overflow-x: scroll !important;
        overflow-y: hidden !important;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        touch-action: pan-x pan-y;
    }

    .maintenance-settings-tab .table-scroll-wrapper > .machine-table {
        display: table !important;
        width: max-content !important;
        min-width: 760px !important;
        table-layout: auto !important;
    }

    .maintenance-settings-tab .machine-table thead {
        display: table-header-group !important;
    }

    .maintenance-settings-tab .machine-table tbody {
        display: table-row-group !important;
    }

    .maintenance-settings-tab .machine-table tr,
    .maintenance-settings-tab .machine-table tr:has(th) {
        display: table-row !important;
        margin: 0 !important;
        padding: 0 !important;
        border: 0 !important;
        border-radius: 0 !important;
        background: transparent !important;
    }

    .maintenance-settings-tab .machine-table th,
    .maintenance-settings-tab .machine-table td,
    .maintenance-settings-tab .machine-table td:not([data-label]) {
        display: table-cell !important;
        width: auto !important;
        min-width: 90px !important;
        max-width: 300px !important;
        padding: var(--spacing-sm) var(--spacing-md) !important;
        text-align: left !important;
        white-space: normal !important;
        vertical-align: middle !important;
    }

    .maintenance-settings-tab .machine-table td::before {
        content: none !important;
        display: none !important;
    }

    .maintenance-settings-tab .machine-table td:has(> .actions-container) {
        min-width: 150px !important;
        white-space: nowrap !important;
    }

    .maintenance-settings-tab .machine-table .actions-container {
        flex-wrap: nowrap !important;
    }

    /* The Settings tab strip itself remains swipeable when all labels do not
       fit on one phone-width row. */
    .settings-tabs > .ctabs-bar {
        overflow-x: scroll !important;
        overflow-y: hidden !important;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        touch-action: pan-x;
    }

    /* Retrofit list controls use the same width as the cards below and wrap
       into compact rows on phones. */
    .settings-tab-content .edit-retrofit-container {
        width: 100% !important;
        max-width: 100% !important;
        padding: var(--spacing-sm) !important;
        padding-bottom: 56px !important;
        box-sizing: border-box !important;
    }

    .settings-tab-content .retrofit-edit-toolbar,
    .settings-tab-content .retrofit-edit-toolbar > .Wt-hboxlayout {
        display: flex !important;
        width: 100% !important;
        min-width: 0 !important;
        flex-wrap: wrap !important;
        gap: 6px !important;
    }

    .settings-tab-content .retrofit-edit-toolbar .edit-search-input {
        flex: 1 1 100% !important;
        width: 100% !important;
        min-width: 0 !important;
    }

    .settings-tab-content .retrofit-edit-toolbar button {
        flex: 1 1 auto !important;
        min-width: 0 !important;
        height: 34px !important;
        padding: 4px 8px !important;
        font-size: var(--font-size-sm) !important;
    }

    /* The 45vw drawer is too narrow on regular phones. Very small phones
       retain the existing 80vw rule from the dedicated 480px breakpoint. */
    .machine-page-layout .panel-left {
        width: clamp(58vw, calc(21.2vw + 282px), 80vw) !important;
        max-width: clamp(58vw, calc(21.2vw + 282px), 80vw) !important;
    }

    /* Part detail popup: tab bar plus future tables need the full width. */
    .part-detail-dialog {
        width: 96vw !important;
        max-width: 96vw !important;
        max-height: 92dvh !important;
    }

    .part-detail-dialog .ctabs-bar {
        flex-wrap: wrap !important;
        gap: 4px !important;
    }

    .part-detail-dialog .part-detail-tab-page {
        min-height: 160px !important;
    }

    /* dvh, not vh: the mobile browser chrome would otherwise push the tab bar
       off the top the moment the address bar collapses. */
    .part-detail-dialog .ctabs {
        max-height: 74dvh !important;
    }

    /* Long part names must wrap rather than widen the dialog. */
    .part-detail-dialog .part-detail-usage-table th,
    .part-detail-dialog .part-detail-usage-table td {
        white-space: normal !important;
        word-break: break-word !important;
    }

    /* Edit + Info keep their own row on a phone too; only the quantity + cart
       pair may wrap if the panel gets very narrow. */
    /* Too narrow for a label next to the icon: the cart button goes icon-only
       and the quantity field takes the freed width. */
    .part-info-cart-label {
        display: none !important;
    }

    .part-info-cart-row .part-info-cart-btn-wrap {
        flex: 0 0 auto !important;
    }

    .part-info-cart-row {
        grid-auto-flow: unset !important;
        grid-template-columns: minmax(0, 1fr) 48px !important;
    }

    .part-info-head-cart .part-info-cart-btn {
        width: 48px !important;
        padding: 0 !important;
    }

    /* BOM edit table: seven columns with fixed px widths cannot fit a phone.
       Each row becomes a card, same mechanism as .machine-table — labels come
       from data-label, written by EditorHelpers::applyMobileLabels. The fixed
       layout and every nth-child width must be released first. */
    .bom-edit-table {
        display: block !important;
        table-layout: auto !important;
    }
    .bom-edit-table thead, .bom-edit-table tbody { display: block !important; }
    .bom-edit-table tr:has(th) { display: none !important; }

    .bom-edit-table th:nth-child(1), .bom-edit-table td:nth-child(1),
    .bom-edit-table th:nth-child(4), .bom-edit-table td:nth-child(4),
    .bom-edit-table th:nth-child(5), .bom-edit-table td:nth-child(5),
    .bom-edit-table th:nth-child(6), .bom-edit-table td:nth-child(6) {
        width: auto !important;
        min-width: 0 !important;
    }

    .bom-edit-table tr {
        display: grid !important;
        grid-template-columns: 1fr;
        border: 1px solid var(--gray-300);
        border-radius: var(--radius-md);
        margin-bottom: var(--spacing-sm);
        padding: var(--spacing-sm) var(--spacing-md);
        background: var(--white);
    }

    .bom-edit-table td {
        display: grid !important;
        grid-template-columns: minmax(88px, 40%) minmax(0, 1fr);
        gap: var(--spacing-sm);
        align-items: center;
        width: auto !important;
        max-width: none !important;
        min-width: 0 !important;
        padding: 4px 0 !important;
        border-bottom: 1px solid var(--gray-100) !important;
        white-space: normal !important;
        text-align: left !important;
    }
    .bom-edit-table td:last-child { border-bottom: 0 !important; }

    .bom-edit-table td::before {
        content: attr(data-label);
        font-weight: 700;
        color: var(--gray-600);
        font-size: var(--font-size-sm);
    }

    /* The delete-button column has an empty header, so no label is reserved. */
    .bom-edit-table td:not([data-label]) {
        display: block !important;
        text-align: center !important;
    }
    .bom-edit-table td:not([data-label])::before { content: none; }

    /* Grid items stretch by default, which would pull the badge and the
       checkbox across the whole value column. */
    .bom-edit-table td > .bom-detail-badge,
    .bom-edit-table td > .bom-nodetails-cb {
        justify-self: start;
    }

    /* Comfortable touch target; the class has no desktop rule of its own. */
    .bom-nodetails-cb {
        width: 22px !important;
        height: 22px !important;
    }

    /* Add row: one card of its own. It has no header row, so its cells carry
       no data-label and stack as plain blocks; the two spacer cells that only
       align it with the list above have nothing to show here. */
    .bom-addrow-table td:nth-child(5),
    .bom-addrow-table td:nth-child(6) {
        display: none !important;
    }
    .bom-addrow-table td { padding: 4px 0 !important; }

    /* Full-width drop targets keep the desktop padding, which costs a third of
       a phone screen per card. */
    .asm-dropzone { padding: 16px 12px !important; }
    .asm-dropzone-sm { padding: 10px 8px !important; }

    /* Reinforces the wide-dialog width for the assembly editor root. The only
       other source sits mid-file, where a later unconditional rule would win. */
    .edit-dialog-lg {
        width: 96vw !important;
        max-width: 96vw !important;
    }

    /* Embed share dialog: the inline setWidth(560) exceeds a phone. The
       snippet textarea must wrap instead of scrolling sideways, and the two
       footer buttons stack full width. */
    .embed-share-dialog {
        width: 94vw !important;
        max-width: 94vw !important;
    }

    .embed-share-dialog .embed-share-snippet {
        width: 100% !important;
        box-sizing: border-box !important;
        min-width: 0 !important;
        white-space: pre-wrap !important;
        word-break: break-all !important;
    }

    .embed-share-dialog .embed-share-modes label {
        display: block !important;
        margin: 6px 0 !important;
    }

    .embed-share-dialog .dialog-buttons {
        display: flex !important;
        flex-direction: column !important;
        gap: 8px !important;
    }

    .embed-share-dialog .dialog-buttons .Wt-btn {
        width: 100% !important;
    }
    /* Version compare: a 5-column table with fixed pixel columns cannot use
       the generic 460px cap. The scroll recipe lives in the desktop block;
       only the bounds and the table reset differ here. */
    .version-compare-dialog {
        width: 96vw !important;
        max-width: 96vw !important;
        max-height: 92dvh !important;
    }

    .Wt-dialog.version-compare-dialog .dialog-layout {
        width: 100% !important;
        max-height: 92dvh !important;
        box-sizing: border-box !important;
    }

    .version-compare-dialog .version-compare-content {
        padding: 12px !important;
    }

    .version-compare-dialog .version-compare-picker {
        gap: 10px !important;
        padding: 10px !important;
    }

    /* Direction marker would strand itself on its own wrapped line. */
    .version-compare-dialog .version-compare-picker-arrow {
        display: none !important;
    }

    .version-compare-dialog .version-compare-picker-field {
        min-width: 0 !important;
        max-width: 100% !important;
        flex: 1 1 140px !important;
    }

    /* Width only. .version-compare-picker-field is a column flex container, so
       a flex-basis here would be read as a HEIGHT and stretch the control. */
    .version-compare-dialog .version-compare-select {
        flex: 0 0 auto !important;
        width: 100% !important;
        min-width: 0 !important;
        max-width: 100% !important;
    }

    .version-compare-dialog .version-compare-table {
        table-layout: auto !important;
        width: 100% !important;
    }

    .version-compare-dialog .version-compare-table th,
    .version-compare-dialog .version-compare-table td {
        width: auto !important;
        min-width: 0 !important;
        white-space: normal !important;
        word-break: break-word !important;
        padding: 6px 6px !important;
    }

    .version-compare-dialog .version-compare-image-cell {
        width: 40px !important;
        min-width: 40px !important;
    }

    .version-compare-dialog .version-compare-scroll {
        overflow-x: auto !important;
    }
    /* Version compare drawings: two panes never fit side by side on a phone,
       and each costs a cold SVG transform, so they stay hidden until the
       reveal button is pressed and then stack. */
    .version-compare-dialog .version-compare-drawings-toggle.Wt-btn {
        display: inline-flex !important;
        align-self: flex-start !important;
        margin-bottom: 10px !important;
    }

    .version-compare-dialog .version-compare-drawings {
        display: none !important;
    }

    .version-compare-dialog .version-compare-drawings.shown {
        display: flex !important;
        flex-direction: column !important;
    }

    .version-compare-dialog .version-compare-drawing-pane {
        flex: 0 0 auto !important;
        width: 100% !important;
        height: 42vh !important;
        min-height: 200px !important;
    }

    /* Part detail bar: menu mode instead of the text buttons, no bar height
       change. Same selectors as the base block, which this follows. */
    .part-detail-bar .part-detail-actions {
        display: none !important;
    }

    .part-detail-bar .part-detail-more {
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
    }

    .part-detail-bar .part-detail-title {
        font-size: var(--font-size-base) !important;
    }

    /* Audit entry detail dialog */
    .audit-detail-dialog {
        width: 96vw !important;
        max-width: 96vw !important;
    }

    .audit-detail-dialog .dialog-layout,
    .audit-detail-dialog .contents,
    .audit-detail-dialog .body,
    .audit-detail-dialog .audit-detail-body {
        width: 100% !important;
    }

    .audit-detail-dialog .audit-detail-grid {
        grid-template-columns: 1fr !important;
    }

    .audit-detail-dialog .audit-detail-diff {
        grid-template-columns: 1fr !important;
    }

    .audit-detail-dialog .audit-detail-value {
        max-height: 30vh !important;
    }

    /* Cart "Quick add": compact popup, detail stacks, toolbar button icon-only. */
    .cart-quick-add-dialog {
        width: min(94vw, 460px) !important;
        max-width: 94vw !important;
        min-width: 0 !important;
    }

    .cart-quick-add-dialog .body {
        padding: 12px !important;
    }

    .cart-quick-add-dialog .cart-quick-add-results {
        max-height: 40dvh !important;
    }

    .cart-quick-add-dialog .cart-quick-add-detail-top {
        flex-direction: column !important;
        align-items: center !important;
    }

    .cart-quick-add-dialog .cart-quick-add-info {
        width: 100% !important;
    }

    .cart-top-right-actions .cart-quick-add-btn {
        font-size: 0 !important;
        width: 32px !important;
        min-width: 32px !important;
        padding: 0 !important;
        justify-content: center !important;
    }

    .cart-top-right-actions .cart-quick-add-btn img {
        margin-right: 0 !important;
    }

    /* Part info dialog: the generic mobile body padding and max-height:none
       would let the panel run past the dialog's max-height. */
    .Wt-dialog.search-part-info-dialog .body {
        padding: 0 !important;
        max-height: calc(min(88dvh, 720px) - 64px) !important;
        overflow-y: auto !important;
    }
}
