
/* ============================================================
   MODERN TEMPLATE STYLESHEET
   Brand palette: #7CBE42 green · #F08C23 orange · #DDEECE light-green · #434143 charcoal · #E7E7E7 gray
   ============================================================ */

:root {
    /* Dynamic portal colour shades */
    --main-color:            #7cbe42;
    --main-color-rgb:        124, 190, 66;
    --main-color-darker-1:   #6aa239;
    --main-color-darker-2:   #5d8f32;
    --main-color-darker-3:   #517c2b;
    --main-color-lighter-1:  #90c85f;
    --main-color-lighter-2:  #9dcf72;
    --main-color-lighter-2-5:#aad585;
    --main-color-lighter-3:  #dfefd0;
    --main-color-lighter-4:  #ecf6e3;
    --main-color-lighter-5:  #f9fcf6;

    /* Brand fixed colours */
    --brand-green:       #7CBE42;
    --brand-orange:      #F08C23;
    --brand-orange-bg:   #FFF3E4;
    --brand-orange-rgb:  240, 140, 35;
    --brand-light-green: #DDEECE;
    --brand-charcoal:    #434143;
    --brand-gray:        #E7E7E7;

    /* Layout */
    --sidebar-width:  240px;
    --topbar-height:  52px;

    /* Sidebar */
    --sidebar-bg:          rgba(255,255,255,0.90);
    --sidebar-border:      rgba(124,190,66,0.20);
    --sidebar-text:        #5a6652;
    --sidebar-text-hover:  #2d3822;
    --sidebar-hover-bg:    rgba(124,190,66,0.09);
    --sidebar-active-bg:   rgba(124,190,66,0.15);
    --sidebar-active-text: var(--main-color-darker-2);

    /* Surface */
    --surface:        #ffffff;
    --surface-alt:    #f7f8f6;
    --content-bg:     #f2f3f0;
    --border:         #E7E7E7;
    --border-strong:  #d0d0cc;

    /* Text */
    --text-primary:   #434143;
    --text-secondary: #6b6870;
    --text-muted:     #9e9ba0;

    /* Interaction */
    --focus-ring: 0 0 0 3px rgba(124, 190, 66, 0.20);

    --radius-sm: 4px;
    --radius:    6px;
    --radius-lg: 10px;
    --radius-xl: 14px;

    --shadow-sm: 0 1px 2px rgba(0,0,0,0.06);
    --shadow:    0 1px 4px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.04);
    --shadow-md: 0 4px 16px rgba(0,0,0,0.08), 0 2px 6px rgba(0,0,0,0.04);
    --shadow-lg: 0 8px 32px rgba(0,0,0,0.10), 0 2px 8px rgba(0,0,0,0.06);

    --transition: 0.15s ease;

    /* Radius aliases kept for gardenWaste/base component compat (e.g. ported editor.css) */
    --alt-radius:        6px;
    --alt-radius-top:    6px 6px 0 0;
    --alt-radius-right:  0 6px 6px 0;
    --alt-radius-bottom: 0 0 6px 6px;
    --alt-radius-left:   6px 0 0 6px;

    /* Gradient design language (carried from login page) */
    --grad-sidebar-start: #527a2a;
    --grad-sidebar-end:   #7d4e1a;
    --grad-accent-start:  #8cc066;
    --grad-accent-end:    #c89050;

    /* Glassmorphism base parameters — override per-element via CSS custom properties */
    --glass-blur:        1px;
    --glass-bg-opacity:  0.5;
    --glass-tint-start:  rgba(238, 238, 238, 0.12);
    --glass-tint-end:    rgba(95, 95, 95, 0.01);
    --glass-tint-angle:    135deg;
    --glass-border-color:  rgba(140,192,102,0.3);
}


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

html { font-size: 14px; -webkit-text-size-adjust: 100%; }

body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
    background: linear-gradient(160deg, #edf4e6 0%, #f4ede4 100%) fixed;
    color: var(--text-primary);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    min-height: 100vh;
}

a { color: var(--main-color); text-decoration: none; }
a:hover { text-decoration: none; color: var(--main-color-darker-1); }
img { max-width: 100%; display: block; }
ul, ol { list-style: none; }
hr { border: 0; border-bottom: 1px solid var(--border); margin: 16px 0; }

::-webkit-input-placeholder { color: var(--text-muted); }
::-moz-placeholder           { color: var(--text-muted); }
:-ms-input-placeholder        { color: var(--text-muted); }
::placeholder                 { color: var(--text-muted); }


/* ============================================================
   LAYOUT SHELL
   ============================================================ */
#app {
    display: flex;
    min-height: 100vh;
    position: relative;
    z-index: 10;
}

/* ============================================================
   SIDEBAR
   ============================================================ */
#sidebar {
    /* Glass override — stronger blur, slightly more opaque than top/footer */
    width: var(--sidebar-width);
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, var(--glass-bg-opacity));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    border-right: 1px solid var(--glass-border-color);
    display: flex;
    flex-direction: column;
    position: fixed;
    left: 0; top: var(--topbar-height); bottom: 0;
    z-index: 300;
    transition: width 0.25s ease, transform 0.25s ease;
    overflow: hidden;
}

/* Scrollable nav area */
#sidebar-scroll {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 8px 0 4px;
}

#sidebar-scroll::-webkit-scrollbar { width: 3px; }
#sidebar-scroll::-webkit-scrollbar-track { background: transparent; }
#sidebar-scroll::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.10); border-radius: 2px; }

/* Footer */
#sidebar-footer {
    padding: 8px 10px 10px;
    border-top: 1px solid var(--sidebar-border);
    flex-shrink: 0;
}

/* Mobile overlay */
#sidebar-overlay {
    display: none;
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.45);
    z-index: 299;
    backdrop-filter: blur(2px);
}
#sidebar-overlay.visible { display: block; }


/* ============================================================
   SIDEBAR COLLAPSE BUTTON
   ============================================================ */
.sidebarCollapseBtn,
.sidebarFooterBtn {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border-radius: var(--radius);
    color: var(--sidebar-text);
    font-size: 12px;
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
    width: 100%;
    border: none;
    background: none;
    font-family: inherit;
}
.sidebarCollapseBtn:hover,
.sidebarFooterBtn:hover { background: var(--sidebar-hover-bg); color: var(--sidebar-text-hover); }
.sidebarCollapseBtn .collapse-icon { font-size: 10px; transition: transform 0.25s ease; }
.sidebar-pin-icon  { font-size: 11px; transition: transform 0.25s ease, color var(--transition); }
.sidebar-hide-icon { font-size: 11px; }
#app.sidebar-pinned .sidebar-pin-icon { transform: rotate(-45deg); color: var(--main-color); }

/* Collapsed (icon-only / pinned) state */
#app.sidebar-collapsed #sidebar   { width: 56px; overflow: visible; }
#app.sidebar-collapsed #sidebar-scroll { overflow: visible; }
#app.sidebar-collapsed #main-wrap { margin-left: 56px; }

#app.sidebar-collapsed .menuText,
#app.sidebar-collapsed .sub-arrow,
#app.sidebar-collapsed .collapseText,
#app.sidebar-collapsed .sidebarBtnText { display: none; }

#app.sidebar-collapsed .sidebarCollapseBtn .collapse-icon { transform: rotate(180deg); }

#app.sidebar-collapsed #menu ul li a {
    justify-content: center;
    padding: 8px 6px;
}
#app.sidebar-collapsed .menuIcon          { width: auto; opacity: 0.85; }
#app.sidebar-collapsed .sidebarCollapseBtn { justify-content: center; padding: 6px; }
#app.sidebar-collapsed .sidebarFooterBtn   { justify-content: center; padding: 6px; }
#app.sidebar-collapsed .reportBug         { justify-content: center; padding: 6px; }

/* Hidden (completely off-screen) state */
#app.sidebar-hidden #sidebar   { transform: translateX(calc(-1 * var(--sidebar-width))); }
#app.sidebar-hidden #main-wrap { margin-left: 0; }

/* Sub-menu flyouts in icon-only mode
   JS only manages .flyout-open; all positioning is pure CSS. */

/* Remove h-padding from the icon-bar ul so each li spans the full 56px sidebar width,
   making left:100% land exactly at the sidebar's right edge. */
#app.sidebar-collapsed #menu > ul { padding: 2px 0; }

/* Every li.has-sub at any level becomes the containing block for its flyout. */
#app.sidebar-collapsed #menu ul li.has-sub { position: relative; }

#app.sidebar-collapsed #menu ul .subMenu {
    display: none;
    position: absolute;
    top: 0;
    left: 100%;
    min-width: 200px;
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, 0.97);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border-color);
    border-radius: var(--radius);
    padding: 4px 4px 4px 0;
    z-index: 400;
    box-shadow: var(--shadow-md);
}
#app.sidebar-collapsed #menu ul li.has-sub.flyout-open > .subMenu { display: block; }
#app.sidebar-collapsed #menu ul .subMenu li a {
    color: var(--text-primary);
    font-size: 12px;
    padding: 6px 10px;
    display: flex;
    align-items: center;
    gap: 8px;
    white-space: nowrap;
    justify-content: flex-start;
}
#app.sidebar-collapsed #menu ul .subMenu li a:hover {
    background: var(--sidebar-hover-bg);
    color: var(--text-primary);
}
/* Show text elements that are hidden in icon-only mode */
#app.sidebar-collapsed #menu ul .subMenu .menuText { display: block; }
#app.sidebar-collapsed #menu ul .subMenu .sub-arrow { display: flex; }


/* ============================================================
   NAVIGATION MENU
   ============================================================ */
#menu { padding: 0; }

#menu ul { padding: 2px 8px; }
#menu ul li { margin-bottom: 1px; }

#menu ul li a {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 10px;
    border-radius: var(--radius);
    color: var(--sidebar-text);
    font-size: 13px;
    font-weight: 500;
    transition: background var(--transition), color var(--transition);
    white-space: nowrap;
    overflow: hidden;
}

#menu ul li a:hover {
    background: var(--sidebar-hover-bg);
    color: var(--sidebar-text-hover);
}

#menu ul li.active > a {
    background: var(--sidebar-active-bg);
    color: var(--sidebar-active-text);
    font-weight: 600;
}

.menuIcon {
    width: 14px;
    font-size: 12px;
    text-align: center;
    flex-shrink: 0;
    opacity: 0.75;
}

#menu ul li a:hover .menuIcon,
#menu ul li.active > a .menuIcon { opacity: 1; }

.menuText { flex: 1; overflow: hidden; text-overflow: ellipsis; }

.sub-arrow {
    font-size: 9px;
    opacity: 0.35;
    flex-shrink: 0;
    transition: transform var(--transition);
}
#menu ul li.has-sub.active > a .sub-arrow { transform: rotate(90deg); opacity: 0.6; }

/* Sub-menus */
#menu ul .subMenu {
    padding: 2px 4px 2px 23px;
    border-left: 1px solid var(--sidebar-border);
    margin-left: 13px;
    margin-bottom: 2px;
}

#menu ul .subMenu li a {
    font-size: 12px;
    padding: 5px 8px;
    color: var(--text-muted);
    font-weight: 400;
}
#menu ul .subMenu li a:hover { color: var(--sidebar-text-hover); }
#menu ul .subMenu li.active > a {
    color: var(--sidebar-active-text);
    font-weight: 500;
}

#menu ul .subMenu .subMenu {
    margin-left: 10px;
    padding-left: 10px;
}

/* Bug report link */
.reportBug {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border-radius: var(--radius);
    color: rgba(176,174,177,0.65);
    font-size: 12px;
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
    width: 100%;
    border: none;
    background: none;
    font-family: inherit;
}
.reportBug:hover { background: var(--sidebar-hover-bg); color: var(--sidebar-text); }
.bugIcon { font-size: 11px; }


/* ============================================================
   MAIN WRAP
   ============================================================ */
#main-wrap {
    margin-left: var(--sidebar-width);
    padding-top: var(--topbar-height);
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-width: 0;      /* prevent flex item expanding past viewport when table content overflows */
    overflow-x: clip;  /* clip without creating a scroll container — keeps position:sticky working */
    transition: margin-left 0.25s ease;
}


/* ============================================================
   TOP BAR
   ============================================================ */
#top-bar {
    position: fixed;
    top: 0; left: 0; right: 0;
    height: var(--topbar-height);
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, var(--glass-bg-opacity));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    border-bottom: 1px solid var(--glass-border-color);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 20px 0 0;
    z-index: 350;
    gap: 12px;
    flex-shrink: 0;
    box-shadow: 0 1px 8px rgba(0,0,0,0.06);
}

#top-bar-left {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
}

#sidebar-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 36px;
    background: none;
    border: none;
    border-radius: var(--radius);
    color: var(--text-secondary);
    font-size: 15px;
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
    flex-shrink: 0;
}
#sidebar-toggle:hover { background: var(--surface-alt); color: var(--text-primary); }

.page-title-icon {
    font-size: 14px;
    color: var(--main-color);
    flex-shrink: 0;
}

#page-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

#top-bar-right {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

#top-bar-brand {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

.topbar-logo {
    height: 26px;
    width: auto;
    flex-shrink: 0;
    filter: brightness(0);
}

.topbar-brand-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.topbar-product {
    font-size: 12px;
    font-weight: 700;
    color: var(--text-primary);
    white-space: nowrap;
    line-height: 1.2;
    letter-spacing: 0.01em;
}

.topbar-portal {
    font-size: 10px;
    color: var(--text-secondary);
    white-space: nowrap;
    line-height: 1.2;
}

.topbar-divider {
    width: 1px;
    height: 20px;
    background: var(--glass-border-color);
    flex-shrink: 0;
    margin: 0 4px;
}


/* ============================================================
   CONTENT
   ============================================================ */
#content {
    flex: 1;
    padding: 24px;
}

/* Headings */
#content h1 {
    font-size: 22px;
    font-weight: 700;
    color: var(--text-primary);
    letter-spacing: -0.01em;
    margin-bottom: 20px;
    padding-bottom: 12px;
    position: relative;
}
#content h1::before {
    content: '';
    position: absolute;
    bottom: 0; left: 0;
    width: 40px; height: 2px;
    background: var(--main-color);
    border-radius: 2px;
}

h1 { font-size: 22px; font-weight: 700; color: var(--text-primary); margin-bottom: 16px; position: relative; display: block; width: 100%; }
h2 { font-size: 17px; font-weight: 600; color: var(--text-primary); margin-bottom: 12px; }
h3 { font-size: 15px; font-weight: 600; color: var(--text-primary); margin-bottom: 10px; }
h4 { font-size: 13px; font-weight: 600; color: var(--text-secondary); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.04em; }

h1::before { content: none; }


/* ============================================================
   FOOTER
   ============================================================ */
#footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 20px;
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, var(--glass-bg-opacity));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    border-top: 1px solid var(--glass-border-color);
    font-size: 12px;
    color: var(--text-muted);
    flex-shrink: 0;
}

/* Back to top */
.backToTop {
    position: fixed;
    bottom: 20px; right: 20px;
    width: 34px; height: 34px;
    border-radius: 50%;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--shadow);
    transition: box-shadow var(--transition), color var(--transition);
    z-index: 100;
}
.backToTop:hover { color: var(--text-primary); box-shadow: var(--shadow-md); }

@keyframes animateArrow {
    0%      { transform: translateY(0);     opacity: 1; }
    50%     { transform: translateY(-150%); opacity: 0; }
    50.01%  { transform: translateY(150%);  opacity: 0; }
    100%    { transform: translateY(0);     opacity: 1; }
}
.btt-icon.animate { animation: animateArrow 0.9s ease-in-out forwards; }


/* ============================================================
   USER PANEL / STATUS WIDGET
   ============================================================ */
#user_panel { position: relative; display: flex; align-items: center; gap: 8px; }

/* Status badge */
#status_badge {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px;
    border-radius: 20px;
    font-size: 11px;
    font-weight: 600;
    border: 1px solid;
    letter-spacing: 0.02em;
}
#user_panel.testing #status_badge { color: #7a4a00; background: #fff4e0; border-color: #fac36a; }
#user_panel.live    #status_badge { color: #2a6534; background: #eaf7ee; border-color: #7ed49a; }

.status-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    display: inline-block;
    flex-shrink: 0;
}
#user_panel.testing .status-dot { background: var(--brand-orange); }
#user_panel.live    .status-dot { background: #3cb86a; animation: pulse-green 2s infinite; }

@keyframes pulse-green {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

/* User button */
#user_button {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 5px 10px 5px 8px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--surface-alt);
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary);
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition);
    user-select: none;
}
#user_button:hover { background: var(--brand-gray); border-color: var(--border-strong); }
#user_button .fa-circle-user { font-size: 16px; color: var(--main-color); }
#user_button .user_chevron { font-size: 9px; color: var(--text-muted); transition: transform var(--transition); }
#user_panel.open #user_button .user_chevron { transform: rotate(180deg); }
#user_button .fa-circle-user, #user_button_icon { font-size: 20px; }

/* Dropdown */
#user_panel_content {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    min-width: 216px;
    overflow: hidden;
    z-index: 500;
}
#user_panel.open #user_panel_content { display: block; }

#user_panel_status_text {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 10px 14px;
    font-size: 11px;
    font-weight: 500;
    border-bottom: 1px solid var(--border);
}
#user_panel.testing #user_panel_status_text { color: #7a4a00; background: #fff9f0; }
#user_panel.live    #user_panel_status_text { color: #2a6534; background: #f3faf5; }

#user_panel_links { padding: 6px; }

.user_panel_link {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 10px;
    border-radius: var(--radius);
    font-size: 13px;
    color: var(--text-primary);
    transition: background var(--transition);
}
.user_panel_link:hover { background: var(--surface-alt); color: var(--text-primary); }
.user_panel_link i { width: 14px; text-align: center; color: var(--text-muted); font-size: 12px; }
.user_panel_logout { color: #c0392b; }
.user_panel_logout:hover { background: #fff5f5; }
.user_panel_logout i { color: #e74c3c; }


/* ============================================================
   SESSION EXPIRY POPUP
   ============================================================ */
.expiryPopup {
    position: fixed;
    top: 14px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 9999;
    display: none;
    align-items: center;
    gap: 8px;
    background: var(--brand-orange-bg);
    border: 1px solid var(--brand-orange);
    color: #7a3c00;
    padding: 8px 18px;
    border-radius: 20px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: var(--shadow-md);
    white-space: nowrap;
    font-family: inherit;
    transition: box-shadow var(--transition);
}
.expiryPopup:hover { box-shadow: var(--shadow-lg); }
.expiryPopupIcon { color: var(--brand-orange); }


/* ============================================================
   BACKGROUND AJAX REQUESTS
   ============================================================ */
#backgroundAjaxRequests {
    position: fixed;
    top: 70px; right: 16px;
    z-index: 9000;
    width: 300px;
    display: none;
}

.backgroundAjaxRequest {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: 12px 14px;
    margin-bottom: 8px;
    font-size: 13px;
    position: relative;
}
.hideRequest { position: absolute; right: 10px; top: 10px; cursor: pointer; color: var(--text-muted); border: none; background: none; }
.hideRequest:hover { color: var(--text-primary); } }
.requestName { font-size: 15px; font-weight: 600; margin-bottom: 4px; }
.requestState { font-size: 10px; text-transform: uppercase; color: var(--text-muted); margin-bottom: 4px; }
.requestText { font-size: 11px; color: var(--text-secondary); }
.requestProgress { width: 100%; margin-top: 6px; }
.requestLink:hover { text-decoration: underline; }

progress[value] {
    -webkit-appearance: none;
    appearance: none;
    border: none;
    width: 100%;
    height: 4px;
    background: var(--brand-gray);
    border-radius: 2px;
}
progress::-webkit-progress-bar  { background: var(--brand-gray); border-radius: 2px; }
progress::-webkit-progress-value{ background: var(--main-color); border-radius: 2px; }
progress::-moz-progress-bar     { background: var(--main-color); border-radius: 2px; }


/* ============================================================
   CARDS & PANELS
   ============================================================ */
.card, .panel {
    background: rgba(255,255,255,0.78);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border: 1px solid rgba(255,255,255,0.55);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 20px;
    margin-bottom: 16px;
}

.card-header, .panel-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border);
}

.card-title, .panel-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
}

/* Section wrapper (replaces .wrapper in gardenWaste) */
.wrapper { max-width: 100%; margin: 0 auto; }
.wrapper_head { max-width: 100%; margin: 0 auto; padding-bottom: 5px; }
.clear { clear: both; }
.margin-top { margin-top: 10px; }


/* ============================================================
   BUTTONS
   ============================================================ */
.buttonRow, .btn-row {
    display: flex;
    gap: 8px;
    flex-flow: row wrap;
    width: 100%;
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    box-sizing: border-box;
    padding: 8px 16px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text-primary);
    font-size: 13px;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition), color var(--transition), box-shadow var(--transition);
    text-align: center;
    white-space: nowrap;
    line-height: 1.4;
    text-decoration: none;
    flex-grow: 1;
    flex-shrink: 0;
}

.btn:hover {
    background: var(--surface-alt);
    border-color: var(--main-color);
    color: var(--main-color);
}

.btn.active,
.btn-primary {
    background: var(--main-color);
    border-color: var(--main-color-darker-1);
    color: #ffffff;
    box-shadow: 0 1px 3px rgba(var(--main-color-rgb), 0.30);
}
.btn.active:hover,
.btn-primary:hover {
    background: var(--main-color-darker-1);
    border-color: var(--main-color-darker-2);
    color: #ffffff;
    box-shadow: 0 2px 8px rgba(var(--main-color-rgb), 0.35);
}

/* Orange / accent variant */
.btn-accent, .btn-orange {
    background: var(--brand-orange);
    border-color: #c9701a;
    color: #ffffff;
}
.btn-accent:hover, .btn-orange:hover {
    background: #c9701a;
    border-color: #a85c12;
    color: #ffffff;
}

.btn-danger {
    background: #e74c3c;
    border-color: #c0392b;
    color: #ffffff;
}
.btn-danger:hover { background: #c0392b; color: #ffffff; }

.btn-ghost {
    background: transparent;
    border-color: transparent;
    color: var(--text-secondary);
}
.btn-ghost:hover { background: var(--surface-alt); border-color: var(--border); color: var(--text-primary); }

.btn-sm { padding: 5px 11px; font-size: 12px; }
.btn-xs { padding: 3px 8px;  font-size: 11px; }

/* Icon-only batch buttons */
.btn-row .btn { flex: 1 1 auto; }

.quarantineBatchBtn {
    flex-grow: 0 !important;
    padding: 7px 12px;
    border-radius: var(--radius);
}
.quarantineBatchBtn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
}

.submitButton {
    width: 100%;
    padding: 11px 16px;
    background: var(--main-color);
    border: 1px solid var(--main-color-darker-1);
    border-radius: var(--radius);
    cursor: pointer;
    font-weight: 600;
    font-size: 14px;
    font-family: inherit;
    color: #ffffff;
    transition: background var(--transition), box-shadow var(--transition);
}
.submitButton:hover {
    background: var(--main-color-darker-1);
    box-shadow: 0 2px 8px rgba(var(--main-color-rgb), 0.30);
}

.btn-bottom-margin { margin-bottom: 10px; }
.btn-full-width, .div-full-width { width: 100%; box-sizing: border-box; }

/* Disabled state */
.disabled, button:disabled, input:disabled, textarea:disabled, select:disabled {
    background: #f0f0ef !important;
    color: var(--text-muted) !important;
    border-color: var(--border) !important;
    cursor: not-allowed !important;
    box-shadow: none !important;
}


/* ============================================================
   TABS
   ============================================================ */
.tabs {
    width: 100%;
    margin-bottom: 16px;
    position: relative;
    /* isolation:isolate walls this widget's own li/dropdown/panel z-index
       fight (2/101/1) off from every OTHER .tabs widget's identical set of
       numbers on the same page - necessary, but not sufficient on its own:
       it only stops the numbers leaking across widgets, it doesn't change
       who wins when TWO WHOLE .tabs widgets overlap (an open dropdown from
       an earlier widget overflowing down into a later one). Neither .tabs
       has an explicit z-index by default, so that comparison still ties
       and falls back to DOM order - the later widget on the page still
       won as a whole atomic layer, dropdown included. z-index below (on
       the :has(hover) state) is what actually fixes that: it temporarily
       promotes ONLY the widget whose dropdown is actually open above every
       sibling widget, rather than trying to statically rank widgets that
       don't know about each other at CSS-authoring time. */
    isolation: isolate;
    z-index: 0;
}
/* Promotes the whole widget above every sibling .tabs on the page only
   while one of its dropdowns is actually open (the :hover that reveals
   the dropdown - see ".tabs > ul > li:hover > ul { display: block; }"
   below) - so an overflowing dropdown can outrank a LATER .tabs widget's
   own tab bar, which a static z-index difference could never do reliably
   since either widget could be the one whose dropdown opens. Falls back
   to the baseline 0 above the instant the hover ends. Must stay well
   under the sidebar (300)/top-bar (400) bands - 500 briefly put an open
   dropdown's whole widget above the fixed top bar too, which only needs
   to beat other .tabs widgets and ordinary page content, nothing fixed. */
.tabs:has(> ul > li:hover) {
    z-index: 50;
}

/* Tab list */
.tabs > ul {
    width: 100%;
    list-style: none;
    display: flex;
    flex-flow: row wrap;
    gap: 3px;
    padding: 0;
    margin: 0;
    position: relative;
    padding-bottom: 0;
}

.tabs > ul li { padding: 0 !important; }
.tabs > ul a { white-space: nowrap; box-sizing: border-box; }

/* Invisible row-break marker, inserted/removed by templateBottom.php's
   tab row-promotion script (flex-basis:100% forces a hard flex-wrap line
   break at this exact point, regardless of the surrounding tabs' widths -
   a standard technique to lock in row membership when reordering wrapped
   items via CSS `order`). Excluded from all the real-tab styling below
   (border/background/glass ::before/hover) since it's not a tab. */
.tabs > ul > li.tab-row-break {
    flex-basis: 100%;
    height: 0;
    min-height: 0;
    margin: 0;
    border: none;
    pointer-events: none;
}
.tabs > ul > li.tab-row-break::before { content: none; }

/* Individual tab - glass recipe on all tabs (active and inactive alike),
   border stays transparent on inactive so only the active tab gets the
   visible glass-border outline below. Needs its own z-index above the
   content panel's (1): backdrop-filter forces every tab <li> to become
   its own stacking context now that ALL tabs carry it (not just the
   active one before this round), which traps the sub-tab dropdown's own
   z-index:101 (below) to rank only WITHIN that li's local context - it
   can no longer reach far enough up the tree to outrank the panel (a
   sibling of the tab bar, not a descendant of any one li). Without an
   explicit z-index here, the li's rank against that sibling panel falls
   back to auto/DOM-order, and the panel (later in source) wins, putting
   dropdowns behind the tab content instead of in front of it. */
.tabs > ul > li {
    position: relative;
    z-index: 2;
    flex: 1 1 auto;
    border: 1px solid transparent;
    border-bottom: none;
    border-radius: var(--radius) var(--radius) 0 0;
    margin-bottom: 1px;
}
/* Glass background lives on ::before, not the li itself. backdrop-filter
   directly on li would make li a "backdrop root" (CSS Filter Effects),
   and the sub-tab dropdown (.tabs > ul > li > ul, below) is a DOM
   descendant of that same li - so the dropdown's own backdrop-filter
   would get confined to sampling only what's painted inside the li's own
   tiny box (mostly just the label text) instead of the real page content
   behind it, which is why the dropdown's blur looked like it wasn't
   doing anything. A ::before pseudo is a SIBLING of the dropdown <ul>
   (both are children of li), not an ancestor of it, so it doesn't sit in
   the dropdown's backdrop-root chain at all - the dropdown's own
   backdrop-filter then resolves up to .tabs (the nearest real backdrop
   root, via isolation:isolate a few rules up) and blurs the actual
   panel/page content behind it correctly. */
.tabs > ul > li::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, var(--glass-bg-opacity));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    transition: background var(--transition);
}

.tabs > ul > li > a {
    display: block;
    width: 100%;
    padding: 10px 16px;
    text-align: center;
    font-size: 13px;
    font-weight: 500;
    color: var(--text-secondary);
    text-overflow: ellipsis;
    overflow: hidden;
    transition: color var(--transition);
    text-decoration: none;
}

/* Sub-tab chevron indicator */
.tabs > ul li > a:after {
    font-family: "Font Awesome 6 Free";
    content: "\f0d7";
    font-weight: 900;
    margin-left: 8px;
    font-size: 10px;
    opacity: 0.5;
}
.tabs > ul li > a:only-child:after { content: ''; margin-left: 0; }

/* Translucent green tint layered on top of the existing sheen gradient
   (same recipe as the base rule above), not a solid fill - a plain
   `background: var(--brand-light-green)` here would fully replace the
   glass background/blur instead of tinting it (same class of bug fixed
   for calendar-event hover, see [[project_experimental_modern_css_polish]]
   round 9). Targets ::before, not li itself, now that the glass
   background/blur lives there (see the base li rule above) -
   backdrop-filter stays inherited from that rule since :hover doesn't
   touch it. */
.tabs > ul > li:hover::before {
    background-image:
        linear-gradient(rgba(221, 238, 206, 0.55) 0 0),
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%);
}
.tabs > ul > li:hover > a { color: var(--main-color); }
/* Every li shares the same base z-index (2), and a dropdown's own
   z-index:101 (below) only wins WITHIN its own li's local stacking
   context - against a SIBLING li (e.g. a lower wrapped row, or the row
   templateBottom.php's promoteActiveRow() just moved to the bottom) it's
   the li's own z-index that gets compared, and ties resolve by
   order-adjusted document position, which the promoted row deliberately
   wins (it's placed last). Without this, an upper row's open dropdown
   rendered underneath the row below it. Explicitly outranking every
   sibling on :hover (whichever li is actually showing its dropdown right
   now) fixes it regardless of row position. */
.tabs > ul > li:hover {
    z-index: 20;
}

/* Active tab - inactive tabs now share the same glass background (see
   .tabs > ul > li above), so all that's left to add here is the visible
   glass-border outline that marks the active one, plus the seam-fix
   margin below. */
.tabs > ul > li:has(a.active) {
    border-color: var(--glass-border-color);
    /* Fine alignment for the panel's ::before notch (css/modern/style.php
       .tabs > div::before) sitting flush against the active tab - tweaked
       by hand, don't "clean up" back to the base tab's 1px. */
    margin-bottom: 0px;
    margin-right: 0px;
}
.tabs > ul > li > a.active {
    color: var(--main-color);
    font-weight: 600;
}

/* Tab content panels - same glassmorphism recipe as the active tab above,
   so the two read as one continuous surface. border-top is deliberately
   NOT part of the border shorthand below - see the ::before rule right
   after this one for why. */
.tabs > div,
.tabs > form {
    display: none;
    border: 1px solid var(--glass-border-color);
    border-top: none;
    padding: 20px;
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, var(--glass-bg-opacity));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    position: relative;
    z-index: 1;
}
/* The panel's top border needs an actual notch cut into it exactly where
   the active tab sits - not just hidden/covered - since a covering patch
   would have to be opaque to fully hide the line, which looks wrong
   against a translucent glass surface (tried and rejected). A notch's
   position/width depends on which tab is active and how long its label
   is, which isn't knowable in static CSS - so the border line lives on
   its own thin pseudo-element (mask-image would otherwise punch a hole
   through the WHOLE panel box, not just its border), sized/positioned by
   --active-tab-left/--active-tab-width custom properties that
   templates/modern/templateBottom.php measures from the real active <li>
   and writes onto .tabs. Hard (same-position) colour stops in the mask
   make the cut a sharp notch rather than a fade. Falls back to no cut
   (full solid line) via the var() defaults before JS has run once. */
.tabs > div::before,
.tabs > form::before {
    content: '';
    position: absolute;
    top: -1px;
    left: -0.8px;
    right: 0;
    height: 1px;
    background: var(--glass-border-color);
    -webkit-mask-image: linear-gradient(to right,
        #000 0, #000 var(--active-tab-left, 0px),
        transparent var(--active-tab-left, 0px), transparent calc(var(--active-tab-left, 0px) + var(--active-tab-width, 0px)),
        #000 calc(var(--active-tab-left, 0px) + var(--active-tab-width, 0px)), #000 100%);
    mask-image: linear-gradient(to right,
        #000 0, #000 var(--active-tab-left, 0px),
        transparent var(--active-tab-left, 0px), transparent calc(var(--active-tab-left, 0px) + var(--active-tab-width, 0px)),
        #000 calc(var(--active-tab-left, 0px) + var(--active-tab-width, 0px)), #000 100%);
}

.tabs.scroll .scroll-icon::before {
    background: none;
}

/* Sub-menu dropdown - same glass recipe as the tabs/panel above it, so the
   whole widget (including its popup) reads as one consistent surface. */
.tabs > ul > li > ul {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 100%;
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, var(--glass-bg-opacity));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border-color);
    border-radius: 0 0 var(--radius) var(--radius);
    box-shadow: var(--shadow-md);
    z-index: 101;
    padding: 4px;
    list-style: none;
}

.tabs > ul > li:hover > ul { display: block; }

.tabs > ul > li > ul > li > a {
    display: block;
    padding: 8px 12px;
    font-size: 13px;
    color: var(--text-primary);
    border-radius: var(--radius-sm);
    transition: background var(--transition);
}
.tabs > ul > li > ul > li:hover a {
    background: var(--brand-light-green);
    color: var(--main-color);
}

/* Scroll tabs */
.tabs.scroll { overflow-x: clip; }
.tabs.scroll > ul { flex-flow: row; flex-wrap: nowrap; white-space: nowrap; }

.tabs.scroll .scroll-icon {
    position: absolute;
    top: 0;
    padding: 10px;
    width: 60px;
    z-index: 2;
    display: block;
    border: 0;
    border-radius: 0;
    cursor: pointer;
    color: var(--main-color);
    background: none;
    font-family: inherit;
    backdrop-filter: none;
    margin-top: -1px;
}
.tabs.scroll .scroll-icon.left  { left: 0;  text-align: left;  background: linear-gradient(to right, var(--surface), transparent); }
.tabs.scroll .scroll-icon.right { right: 0; text-align: right; background: linear-gradient(to left,  var(--surface), transparent); }
.tabs.scroll .scroll-icon.left:hover  { padding-left:  20px; }
.tabs.scroll .scroll-icon.right:hover { padding-right: 20px; }

/* Mini tabs */
.tabs.mini > ul > li { flex: 0 1 auto; }

/* Display sub-tab name beneath label */
.tabs.displaySubTab > ul > li > a { padding-bottom: 28px; }
.tabs.displaySubTab > ul > li > a:before {
    content: attr(data-selected-sub-tab);
    position: absolute;
    top: 28px;
    font-size: 11px;
    left: 50%;
    transform: translateX(-50%);
    max-width: 100%;
    padding: 0 10px;
    box-sizing: border-box;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    color: var(--text-muted);
    font-weight: 400;
}

/* Left tabs */
.tabs.leftTabs { display: flex; flex-flow: row; }
.tabs.leftTabs > ul { flex-flow: column; flex: 1 10 auto; max-width: 220px; border-bottom: none; gap: 2px; padding-right: 0; }
.tabs.leftTabs > ul > li {
    flex: 0 1 auto;
    border-radius: var(--radius) 0 0 var(--radius);
    border: 1px solid transparent;
    border-right: none;
    margin-bottom: 0;
    margin-right: 1px;
}
/* Mirrors the horizontal-tabs active/panel glass treatment above - seam
   side (right, since the tab column sits left of the content here) stays
   solid var(--surface) for the same reason: it exists to paint over the
   tab list's own border and must stay opaque to actually hide it. Same
   fix as the horizontal version too: needs the full border-right
   (style+width), not just -color - the base rule above sets
   border-right: none, so a *-color longhand alone never painted anything.
   No background/backdrop-filter here anymore - the shared base
   .tabs > ul > li::before rule already glasses every tab including this
   one; duplicating backdrop-filter directly on li would re-introduce the
   nested-backdrop-root bug that broke this dropdown's own blur (see that
   rule's comment). */
.tabs.leftTabs > ul > li:has(a.active) {
    border-color: var(--glass-border-color);
}
.tabs.leftTabs > div { flex: 100 1 100%; border-radius: 0 var(--radius-lg) var(--radius-lg) 0; border: 1px solid var(--glass-border-color); border-left: none; position: relative; }
/* Vertical mirror of the horizontal notch-cut above - seam is the LEFT
   border here (tab column sits to the left of the panel), cut along the
   vertical axis using --active-tab-top/--active-tab-height instead of
   the horizontal pair. Must fully override the horizontal ::before's
   right/height with explicit right:auto/height:auto - a leftover right:0
   from that rule would conflict with this rule's left+width. */
.tabs.leftTabs > div::before {
    top: -0.8px;
    bottom: 0;
    right: auto;
    height: auto;
    left: -1px;
    width: 1px;
    -webkit-mask-image: linear-gradient(to bottom,
        #000 0, #000 var(--active-tab-top, 0px),
        transparent var(--active-tab-top, 0px), transparent calc(var(--active-tab-top, 0px) + var(--active-tab-height, 0px)),
        #000 calc(var(--active-tab-top, 0px) + var(--active-tab-height, 0px)), #000 100%);
    mask-image: linear-gradient(to bottom,
        #000 0, #000 var(--active-tab-top, 0px),
        transparent var(--active-tab-top, 0px), transparent calc(var(--active-tab-top, 0px) + var(--active-tab-height, 0px)),
        #000 calc(var(--active-tab-top, 0px) + var(--active-tab-height, 0px)), #000 100%);
}

.tabs.leftTabs > ul li > a:after { content: "\f0da"; font-family: "Font Awesome 6 Free"; font-weight: 900; }
.tabs.leftTabs > ul li > a:only-child:after { content: ''; }
.tabs.leftTabs > ul > li > ul { top: 0; left: 100%; border-left: 1px solid var(--glass-border-color); min-width: 180px; }

/* Tab search */
.tabSearchInput {  }
.tabSearchInput .labelLeft, .tabSearchInput input[type="text"] { border-radius: 0 !important; }
.tabSearchInput input[type="text"] { border: 0; border-right: 1px solid var(--border); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); height: 42px; }
.tabs.limitTabDropDown > ul > li > ul { max-height: 280px; overflow-y: auto; }

/* Mobile tabs */
@media only screen and (max-width: 600px) {
    .tabs > div, .tabs > form { padding: 12px; }
    /* Stack into one flush joined list, not separate floating rounded
       pills - the desktop .tabs > ul's gap:3px still applies once
       flex-flow switches to column here, so it has to be zeroed
       explicitly, not just left off the item rule below. Adjacent
       borders collapse into a single shared 1px line via
       margin-bottom:-1px (list-group overlap trick) instead of doubling
       up; the hovered/active item's z-index is bumped above its
       neighbours so its own border isn't hidden underneath whichever
       neighbour happens to paint later in DOM order. */
    .tabs:not(.scroll) > ul { flex-flow: column; gap: 0; border-bottom: none; }
    .tabs:not(.scroll) > ul > li {
        border: 1px solid var(--border);
        border-radius: 0;
        margin-bottom: -1px;
    }
    .tabs:not(.scroll) > ul > li:first-child { border-radius: var(--radius) var(--radius) 0 0; }
    /* Bottom stays flat (0), not rounded - the content panel below flows
       directly on from the last tab (.tabs > div/form is flat on top,
       only rounded at the bottom, same as desktop), so a rounded bottom
       corner here would leave a visible gap-like notch where the two
       don't actually meet. */
    .tabs:not(.scroll) > ul > li:last-child { margin-bottom: 0; }
    /* Each li is its own stacking context (position:relative + z-index on
       the base rule), so a li's dropdown (z-index:101) can only win
       against elements INSIDE that same li - against a SIBLING li (e.g.
       the active tab stacked below the one whose dropdown is open, in
       this column layout) it's the li's OWN z-index that gets compared,
       not its dropdown's. Giving :hover and :has(a.active) the same
       z-index was a tie DOM order resolved in the active tab's favour,
       so it painted over an earlier tab's open dropdown. :hover (a
       dropdown is actually open) now outranks a merely-active tab so the
       open dropdown always wins regardless of stack order. */
    .tabs:not(.scroll) > ul > li:has(a.active) {
        border-color: var(--main-color);
        z-index: 5;
    }
    .tabs:not(.scroll) > ul > li:hover {
        border-color: var(--main-color);
        z-index: 10;
    }
}
@media only screen and (max-width: 1000px) {
    .tabs .tabSearchInput .labelLeft { display: none; }
    .tabs .tabSearchInput input[type="text"] { border-left: 1px solid var(--border); }
}


/* ============================================================
   FILTER BARS
   ============================================================ */
/* position+z-index is required, not decorative: js/forms.js sets
   dropdownParent: jQuery(this).parent() for every select2 (instead of
   Select2's normal default of appending the dropdown to <body>), so a
   select2 inside .filterBar keeps its open dropdown nested INSIDE this
   element rather than escaping it. backdrop-filter already forces
   .filterBar to form its own stacking context, but without an explicit
   z-index that context only gets ordinary paint priority - any later
   sibling content on the page that ALSO forms a stacking context (this
   app gives backdrop-filter to most things - table rows, the calendar,
   etc., see [[project_experimental_modern_css_polish]]) can still paint
   over the whole thing, dropdown included, regardless of the dropdown's
   own z-index (9999 further down this file), since that number only
   ever gets compared within .filterBar's own trapped context. */
.filterBar {
    position: relative;
    z-index: 10;
    width: 100%;
    box-sizing: border-box;
    margin-bottom: 10px;
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, var(--glass-bg-opacity));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border-color);
    border-radius: var(--radius-lg);
    padding: 12px 14px;
    display: flex;
    flex-flow: row wrap;
    align-items: center;
    gap: 8px;
    box-shadow: var(--shadow-sm);
}

/* Primary search filter bar */
.filterBar.searchFilterBar {
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, var(--glass-bg-opacity));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border-color);
}

.filterBarAlt { border-top-left-radius: 0; }

.filterBar form {
    width: 100%;
    padding: 0;
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
    gap: 8px;
    align-items: center;
}

.filterBar .formItem {
    width: auto;
    flex-grow: 1;
    margin: 0;
    min-width: 140px;
}

.filterBar .formItem label { display: none; } /* hide labels in filter bars */

.filterBar .btn {
    padding: 0 14px;
    height: 38px;
    font-size: 12px;
}

/* Compact inputs in filter bars */
.filterBar input[type="text"],
.filterBar input[type="number"],
.filterBar input[type="search"],
.filterBar select {
    height: 38px;
    padding: 0 10px;
    font-size: 13px;
}

.filterBar .select2.select2-container { height: 38px; }
.filterBar .select2.select2-container .select2-selection { height: 36px; }
.filterBar .select2.select2-container .select2-selection .select2-selection__rendered {
    height: auto;
    line-height: 34px;
    padding-top: 0;
}

.filterBar .formItemFlex label {
    width: 38px;
    height: 38px;
    font-size: 13px;
}

/* Search input (left-icon variant) */
.searchInput {
    flex: 100 1 300px;
    margin-bottom: 0 !important;
}

.searchFilterBar > .btn { flex: 0 1 auto; }

/* Date range filter */
.dateRangeFilter {
    display: flex;
    flex-flow: row;
    align-items: center;
    gap: 8px;
    flex: 1 0 auto;
    color: var(--text-secondary);
    font-size: 12px;
    font-weight: 600;
}

.filterBar form .doubleInput {
    width: auto;
    flex-grow: 1;
    margin: 0;
    display: flex;
    flex-flow: row wrap;
    gap: 6px;
}

/* Batch action bar (sticky bottom) */
#quarantineBatchBar {
    position: sticky;
    bottom: 0;
    z-index: 100;
    border-radius: 0;
    margin-top: 10px;
    background: var(--surface) !important;
    border: none !important;
    border-top: 2px solid var(--main-color) !important;
    box-shadow: 0 -4px 16px rgba(0,0,0,0.08);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 20px;
}
#quarantineBatchBar #quarantineSelectedCount {
    font-size: 13px;
    font-weight: 600;
    color: var(--main-color);
    flex-shrink: 0;
}

/* Filter builder */
#filtersListDisplay { display: none; }
#filtersListContainer {
    width: 100%;
    min-height: 50px;
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius);
    padding: 10px;
    position: relative;
}
#filtersListBackground {
    color: var(--text-muted);
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    text-transform: uppercase;
    font-size: 16px;
    z-index: 0;
}
#filtersList { width: 100%; }
.filterGroup {
    display: flex;
    flex-flow: row;
    border: 1px solid var(--border);
    width: 100%;
    padding: 6px;
    align-items: stretch;
    justify-content: center;
    gap: 8px;
    margin-bottom: 8px;
    border-radius: var(--radius);
}
.filterGroupSortable {
    flex: 1 1 auto;
    border: 1px solid var(--border);
    min-height: 52px;
    padding: 6px;
    border-radius: var(--radius-sm);
}
.filterContainer {
    display: flex;
    flex-flow: row;
    border: 1px solid var(--border);
    width: 100%;
    padding: 6px;
    margin-bottom: 8px;
    align-items: stretch;
    gap: 8px;
    background: var(--surface-alt);
    border-radius: var(--radius);
    z-index: 1;
    position: relative;
}
.filterContainer:last-of-type { margin-bottom: 0; }
.filterContainer .formItem { flex: 1 1 180px; }
.filterOperator {
    display: flex;
    flex-flow: row;
    border: 1px solid var(--border);
    width: 100%;
    padding: 6px;
    gap: 6px;
    margin-bottom: 8px;
    border-radius: var(--radius-sm);
}
.handle { flex: 0 0 auto; padding: 0 8px; display: flex; align-items: center; cursor: grab; color: var(--text-muted); }
.filterGroup .filterGroup:last-of-type,
.filterGroup .filterContainer:last-of-type,
.filterGroup .filterOperator:last-of-type { margin-bottom: 0; }

.deleteFilterBtn {
    flex: 0 0 auto;
    padding: 0 10px;
    align-items: center;
    display: flex;
    cursor: pointer;
    background: #e74c3c;
    color: #ffffff;
    border-radius: var(--radius-sm);
}
.deleteFilterBtn:hover { background: #c0392b; }


/* ============================================================
   FORMS
   ============================================================ */
form {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
}

fieldset {
    width: 100%;
    margin: 0 auto 12px;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
legend {
    padding: 0 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-secondary);
}

.formColumns, .dataColumns {
    display: flex;
    flex-flow: row wrap;
    width: 100%;
    gap: 0 12px;
    margin-bottom: 12px;
}
.formColumnsSmall { display: flex; flex-flow: row wrap; width: 100%; gap: 0 10px; }

.formColumnGroup, .dataColumnGroup { flex: 1 1 500px; }
.dataColumnHalfWidth { box-sizing: border-box; max-width: 50%; }

.formItem {
    width: 100%;
    margin: 0 auto 12px;
    position: relative;
    line-height: 1.4;
}
.formItem:last-child { margin-bottom: 0; }
td .formItem { margin-bottom: 0; }
.formItemNoMarginBottom { margin-bottom: 0 !important; }
.formItemNoWidth { width: auto; }

.formColumns .formItem  { flex: 1 1 500px; }
.formColumnsSmall .formItem { flex: 1 1 250px !important; }

/* Label */
.formItem > label {
    display: block;
    width: 100%;
    padding-bottom: 5px;
    margin-bottom: 6px;
    text-align: left;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    position: relative;
}

label::before { content: none; }

.formItem .inputInfo {
    font-size: 11px;
    color: var(--text-muted);
    padding-top: 4px;
    font-style: italic;
}

.formItem .rightLinks {
    float: right;
    position: relative;
    top: -3px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.formItem .rightLinks a { margin-left: 0; font-size: 12px; }

/* Icon-left input layout */
.formItemFlex {
    display: flex;
    flex-flow: row nowrap;
    align-items: flex-start;
    width: 100%;
    position: relative;
}

.formItemFlex label {
    flex: 0 0 auto;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 42px;
    height: 42px;
    background: var(--main-color);
    color: #ffffff;
    border-radius: var(--radius) 0 0 var(--radius);
    font-size: 14px;
}
/* Checkbox + icon (e.g. examples.php's "Checkbox Icon Example") - white
   background and the radius flipped to round the RIGHT side instead of
   the left. Higher specificity than the rule above (an extra :has()
   qualifier + class) so it wins for this case without touching the
   normal text/select2 icon-box treatment. */
/* Checkbox + icon (e.g. examples.php's "Checkbox Icon Example") - the
   checkbox's own container, to the RIGHT of the icon box, gets a white
   background and the radius flipped to round ITS right side, completing
   the icon box + checkbox as one joined pill - same "labelLeft ~ X"
   pattern already used for .select2-container further down. The icon
   box itself (.labelLeft, above) is untouched here, it was already
   correct as ported. */
.labelLeft ~ .squaredCheck,
.labelLeft ~ .squaredCheckSmall {
    background: #fff;
    border: 1px solid var(--border-strong);
    border-left: 0;
    height: 42px;
    padding: 0 12px;
    box-sizing: border-box;
    border-radius: 0 var(--radius) var(--radius) 0 !important;
}

.inputContainer { flex: 1 1 200px; position: relative; width: 100%; }
.inputContainer:has(.squaredCheck) { width: fit-content; }

/* Core inputs */
input[type="password"],
input[type="text"],
input[type="number"],
input[type="email"],
input[type="tel"],
input[type="search"],
select {
    width: 100%;
    height: 42px;
    border: 1px solid var(--border-strong);
    padding: 0 12px;
    color: var(--text-primary);
    box-sizing: border-box;
    border-radius: var(--radius);
    font-family: inherit;
    font-size: 13px;
    background: var(--surface);
    transition: border-color var(--transition), box-shadow var(--transition);
    outline: none;
}

input[type="password"]:focus,
input[type="text"]:focus,
input[type="number"]:focus,
input[type="email"]:focus,
input[type="search"]:focus,
select:focus {
    border-color: var(--main-color);
    box-shadow: var(--focus-ring);
    background: #fafff7;
}


/* Textarea */
.formItem textarea, textarea {
    width: 100%;
    min-height: 110px;
    border: 1px solid var(--border-strong);
    padding: 10px 12px;
    resize: vertical;
    box-sizing: border-box;
    color: var(--text-primary);
    border-radius: var(--radius);
    font-family: inherit;
    font-size: 13px;
    background: var(--surface);
    transition: border-color var(--transition), box-shadow var(--transition);
    outline: none;
    line-height: 1.5;
}
textarea:focus { border-color: var(--main-color); box-shadow: var(--focus-ring); background: #fafff7; }

/* File input */
input[type="file"] {
    width: 100%;
    border: 1px solid var(--border-strong);
    padding: 10px 12px;
    color: var(--text-primary);
    background: var(--surface);
    border-radius: var(--radius) var(--radius) 0 0;
    box-sizing: border-box;
    font-family: inherit;
    font-size: 13px;
}
.filenameDisplay {
    width: 100%;
    padding: 10px 12px;
    color: #ffffff;
    background: var(--main-color);
    border-radius: 0 0 var(--radius) var(--radius);
    box-sizing: border-box;
    font-size: 12px;
}

/* Radius helpers for joined inputs */
.labelLeft { border-radius: var(--radius) 0 0 var(--radius) !important; }
.labelLeft::before { display: none; }
.inputRight  { border-radius: 0 var(--radius) var(--radius) 0 !important; }
.inputLeft   { border-radius: var(--radius) 0 0 var(--radius) !important; }
.inputNoRadius { border-radius: 0 !important; }
/* !important + the extra .select2 class (matching the generic
   .select2.select2-container rule's own selector shape) - without them
   this tied on specificity (2 classes each) with that later rule's own
   border-radius:var(--radius) (all 4 corners), and since it's declared
   AFTER this one in the file, it silently won the tie, leaving the left
   side rounded instead of flat against the icon box. */
.labelLeft ~ .select2.select2-container { border-radius: 0 var(--radius) var(--radius) 0 !important; }

/* Validation */
.requirementsContainer {
    position: relative;
    top: 4px;
    font-size: 11px;
    line-height: 1.3;
    display: none;
    background: #e74c3c;
    border-radius: var(--radius);
    z-index: 1;
}
.requirementsContainer::before {
    content: '';
    position: absolute;
    top: -5px;
    left: calc(100% - 50px);
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    border-bottom: 10px solid #e74c3c;
}
.validationRequirements, .requiredRequirements {
    padding: 5px 8px;
    color: white;
    text-align: left;
    text-transform: uppercase;
    font-size: 11px;
}
.validationInvalid, .requiredInvalid, .checkInvalid, .invalid { border-color: #e74c3c !important; }
.check {
    padding: 3px 8px;
    color: white;
    background: var(--main-color-darker-2);
    flex: 1 1 auto;
    display: none;
    text-align: left;
    text-transform: uppercase;
    font-size: 11px;
}
.requiredText { color: #e74c3c; padding-left: 4px; }

/* Password toggle */
.showPasswordToggle {
    flex: 0 0 auto;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 42px;
    height: 42px;
    margin-left: -42px;
    cursor: pointer;
    color: var(--text-muted);
}
.showPasswordToggle:hover { color: var(--text-primary); }
.passwordPaddingRight { padding-right: 42px !important; }

/* Number stepper */
.numberScroller { flex: 0 0 auto; display: flex; flex-direction: column; width: 42px; height: 42px; cursor: pointer; }
.numberStepUp, .numberStepDown {
    flex: 1 0 auto;
    background: var(--main-color);
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #ffffff;
    font-size: 11px;
    transition: background var(--transition);
}
.numberStepUp  { border-radius: 0 var(--radius) 0 0; }
.numberStepDown{ border-radius: 0 0 var(--radius) 0; }
.numberStepUp:hover, .numberStepDown:hover { background: var(--main-color-darker-1); }

/* CHECKBOX */
.squaredCheck { position: relative; display: flex; align-items: center; }
.squaredCheck::before { content: none; }
.squaredCheck input[type=checkbox] {
    position: absolute;
    height: 1px; width: 1px;
    overflow: hidden;
    clip: rect(1px,1px,1px,1px);
    white-space: nowrap;
}
.squaredCheck .squaredCheck-checkbox {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: relative;
    margin-bottom: 0;
    padding-bottom: 0;
    height: 20px; width: 20px;
}
.squaredCheck .squaredCheck-checkbox:before {
    content: "";
    display: inline-block;
    width: 18px; height: 18px;
    border-radius: var(--radius-sm);
    background: var(--surface);
    border: 1.5px solid var(--border-strong);
    position: relative;
    cursor: pointer;
    transition: background-color var(--transition), border-color var(--transition);
}
.squaredCheck input[type=checkbox]:checked + .squaredCheck-checkbox:before {
    background: var(--main-color);
    border-color: var(--main-color);
}
.squaredCheck input[type=checkbox] + .squaredCheck-checkbox:after {
    content: "✔";
    color: var(--main-color);
    font-size: 12px;
    position: absolute;
    left: 45%; top: 50%;
    cursor: pointer;
    opacity: 0;
    transform: translate(-50%, -50%);
    transition: opacity 0.2s ease;
    line-height: 1;
}
.squaredCheck input[type=checkbox]:checked + .squaredCheck-checkbox:after { opacity: 1; color: #ffffff; }
.squaredCheck input[type=checkbox]:hover + .squaredCheck-checkbox:after { opacity: 0.3; }
.squaredCheck input[type=checkbox]:checked:hover + .squaredCheck-checkbox:after { opacity: 1; }
.squaredCheck:focus-within .squaredCheck-checkbox::before { border-color: var(--main-color); box-shadow: var(--focus-ring); }

/* Small checkbox (used in tables) */
.squaredCheckSmall { position: relative; display: flex; align-items: center; }
.squaredCheckSmall::before { content: none; }
.squaredCheckSmall input[type=checkbox] {
    position: absolute;
    opacity: 0; overflow: hidden;
    clip: rect(0,0,0,0);
    height: 10px; width: 10px;
    padding: 0; border: 0; left: 0;
}
.squaredCheckSmall .squaredCheck-checkbox {
    display: block;
    width: 16px; height: 16px;
    background: var(--surface);
    border: 1.5px solid var(--border-strong);
    cursor: pointer;
    border-radius: var(--radius-sm);
}
.squaredCheckSmall .squaredCheck-checkbox:after {
    content: "✔";
    position: absolute;
    top: 50%; left: 50%;
    background: transparent;
    opacity: 0;
    transform: translate(-50%, -50%);
    font-size: 11px;
}
.squaredCheckSmall input[type=checkbox]:hover + .squaredCheck-checkbox:after { opacity: 0.3; }
.squaredCheckSmall input[type=checkbox]:checked + .squaredCheck-checkbox { background: var(--main-color); border-color: var(--main-color); }
.squaredCheckSmall input[type=checkbox]:checked + .squaredCheck-checkbox:after { opacity: 1; color: #ffffff; }
.squaredCheckSmall > label { margin-bottom: 0; }

/* Radio */
.circledRadio {
    width: 42px; height: 42px;
    position: relative;
    background: var(--main-color);
    display: inline-block;
    border-radius: 50%;
}
.circledRadio label {
    width: 40px; height: 40px;
    cursor: pointer;
    position: absolute;
    left: 1px; top: 1px;
    background: var(--surface);
    margin: 0;
    border-radius: 50%;
}
.circledRadio label:after {
    content: '';
    width: 28px; height: 28px;
    position: absolute;
    top: 6px; left: 6px;
    background: var(--main-color);
    opacity: 0;
    border-radius: 50%;
    transition: opacity var(--transition);
}
.circledRadio label:before { content: none; }
.circledRadio label:hover::after { opacity: 0.3; }
.circledRadio input[type=radio] { visibility: hidden; }
.circledRadio input[type=radio]:checked + label:after { opacity: 1; }
.disabledRadio { background: #ccc; }

.circledRadioSmall {
    width: 25px; height: 25px;
    position: relative;
    background: var(--main-color);
    display: inline-block;
    border-radius: 50%;
}
.circledRadioSmall label {
    width: 23px; height: 23px;
    cursor: pointer;
    position: absolute;
    left: 1px; top: 1px;
    background: var(--surface);
    margin: 0;
    border-radius: 50%;
}
.circledRadioSmall label:after {
    content: '';
    width: 17px; height: 17px;
    position: absolute;
    top: 3px; left: 3px;
    background: var(--main-color);
    opacity: 0;
    border-radius: 50%;
    transition: opacity var(--transition);
}
.circledRadioSmall label:before { content: none; }
.circledRadioSmall label:hover::after { opacity: 0.3; }
.circledRadioSmall input[type=radio] { visibility: hidden; }
.circledRadioSmall input[type=radio]:checked + label:after { opacity: 1; }

/* Multi option */
.multiOptionContainer { display: flex; flex-flow: row wrap; gap: 8px; }
.verticalOptions { flex-flow: column; width: fit-content; }
.multiOptionOption { display: flex; flex-flow: row; align-items: center; }
.inputText { display: inline-block; padding: 0 0 0 8px; position: relative; }
.centerAlignInput { width: min-content; }

/* Block options */
.blockOptionContainer { gap: 0; }
/* overflow:hidden clips .blockOptionLabel's own white background (below)
   to whatever radius this wrapper has on first/last-of-type - the label
   is a separate inner element with its own square corners, so without
   this its flat white corners painted straight over the wrapper's
   rounded ones (same "child's flat corners paint over the parent's
   curve" issue already fixed for tabs and the accordion, see
   [[project_experimental_modern_css_polish]]). One declaration here
   covers both the horizontal and vertical variants, rather than
   duplicating matching radius onto the label for every first/last case. */
.blockOptionContainer .multiOptionOption { border: 1px solid var(--border-strong); border-left: 0; overflow: hidden; }
.blockOptionContainer .multiOptionOption:first-of-type { border-left: 1px solid var(--border-strong); border-radius: var(--radius) 0 0 var(--radius); }
.blockOptionContainer .multiOptionOption:last-of-type  { border-radius: 0 var(--radius) var(--radius) 0; }
/* Vertical variant (.verticalOptions.blockOptionContainer, switches
   .multiOptionContainer to flex-flow:column) was a complete gap - the
   rules above are horizontal-only (border collapses on the LEFT edge,
   radius on the left/right ends), which is the wrong axis once stacked
   as a column: borders don't collapse between rows at all (double-thick
   horizontal lines) and the first/last items get rounded on their
   left/right sides instead of top/bottom. Mirrors the horizontal
   pattern exactly, just rotated to the vertical axis, same as
   css/forms.css's own .verticalOptions.blockOptionContainer treatment
   for the base theme. Higher specificity (.verticalOptions adds a
   class) than the rules above, so this correctly wins for this variant. */
.verticalOptions.blockOptionContainer .multiOptionOption { border: 1px solid var(--border-strong); border-top: 0; }
.verticalOptions.blockOptionContainer .multiOptionOption:first-of-type { border-top: 1px solid var(--border-strong); border-radius: var(--radius) var(--radius) 0 0; }
.verticalOptions.blockOptionContainer .multiOptionOption:last-of-type  { border-radius: 0 0 var(--radius) var(--radius); }
.blockOption { position: absolute; opacity: 0; width: 0; height: 0; }
.blockOptionLabel { cursor: pointer; padding: 10px 16px; color: var(--text-primary); font-size: 13px; background: #fff; }
.blockOptionLabel::before { content: none; }
.blockOption:checked + .blockOptionLabel { background: var(--main-color); color: #ffffff; }

/* Separated value list */
.seperatedValueList.combined { border: 1px solid var(--border-strong); border-radius: var(--radius); background: var(--surface-alt); }
.seperatedValueListDisplay {
    border-radius: var(--radius) var(--radius) 0 0;
    border: 1px solid var(--border-strong);
    border-bottom: 0;
    min-height: 34px;
    padding: 8px;
    display: flex;
    gap: 6px;
    background: var(--surface-alt);
    flex-flow: row wrap;
}
.seperatedValueList.combined .seperatedValueListDisplay { border: 0; border-radius: 0; background: none; }
.seperatedValueListDisplay .value {
    border-radius: var(--radius);
    background: var(--main-color);
    color: #ffffff;
    padding: 4px 10px;
    cursor: pointer;
    white-space: nowrap;
    font-size: 12px;
}
.seperatedValueListInput { border-radius: 0 0 var(--radius) var(--radius) !important; }
.seperatedValueList.combined .seperatedValueListInput { border: 0; border-radius: 0 !important; background: none; flex: 1 1 50px; padding: 5px; height: auto; }
.seperatedValueList.combined .seperatedValueListInputContainer { flex: 1 1 50px; position: relative; }
.seperatedValueListSuggestions { display: none; position: absolute; border-top: 0; background: var(--surface); border: 1px solid var(--border); width: 100%; z-index: 1000; border-radius: 0 0 var(--radius) var(--radius); box-shadow: var(--shadow); }
.seperatedValueListSuggestions.showSuggestions { display: block; }
.seperatedValueListSuggestion { padding: 8px 12px; cursor: pointer; font-size: 13px; }
.seperatedValueListSuggestion.highlighted,
.seperatedValueListSuggestion:hover { background: var(--brand-light-green); color: var(--main-color); }

/* Autofill */
.autofillResults {
    width: 100%;
    box-sizing: border-box;
    background: var(--surface);
    border: 1px solid var(--border);
    border-top: 0;
    position: absolute;
    top: 100%;
    display: none;
    z-index: 1000;
    border-radius: 0 0 var(--radius) var(--radius);
    box-shadow: var(--shadow-md);
}
.autofillResult { width: 100%; padding: 10px 12px; font-size: 13px; }
.autofillResult:hover { background: var(--brand-light-green); cursor: pointer; }

/* Dropzone */
.dropzone {
    width: 100%;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    padding: 14px;
    color: var(--text-primary);
    background: var(--surface);
}
.dropzoneStyle {
    width: 100%;
    padding: 24px;
    border: 2px dashed var(--border-strong);
    border-radius: var(--radius);
    text-align: center;
    cursor: pointer;
    color: var(--text-secondary);
    /* js/forms.js initializes Dropzone.js directly on the element
       carrying THIS class (`new Dropzone(this, {...})` where `this` is
       .dropzoneStyle) - the real widget never actually gets a plain
       "dropzone" class (checked js/dropzone/dropzone.js: it only ever
       reads that class, never adds it), so the .dropzone rule above -
       with its own nice var(--surface) white background - is dead code
       that never actually applies to it. This is the real element, so
       the background belongs here. */
    background: var(--surface);
    transition: border-color var(--transition), background var(--transition);
}
.dropzoneStyle:hover { border-color: var(--main-color); background: var(--brand-light-green); }
.dz-upload { display: block; background: var(--main-color-lighter-2); height: 4px; width: 0; border-radius: 2px; }
.dz-filetype { color: var(--main-color-lighter-2); }
.dz-success-mark, .dz-error-mark { display: none; }
.dz-remove { color: var(--main-color-lighter-3); }

/* Gallery */
.galleryContainer { display: flex; flex-flow: row wrap; width: 100%; gap: 10px; }
.galleryFile { max-width: 260px; height: 260px; flex: 1 1 180px; border: 1px solid var(--border); border-radius: var(--radius); padding: 10px; display: flex; flex-flow: column; }
.galleryFile:hover { background: var(--brand-light-green); cursor: pointer; }
.galleryFile.selected { background: var(--main-color-lighter-4); border-color: var(--main-color); }
.galleryFilePreview { width: 100%; flex: 1 1 auto; display: flex; font-size: 100px; background-position: center; background-size: contain; background-repeat: no-repeat; align-content: center; }
.galleryFilePreview i { margin: auto; color: var(--main-color-lighter-2); }
.galleryFileName { width: 100%; text-align: center; flex: 0 1 auto; background: var(--main-color); border-radius: 0 0 var(--radius) var(--radius); color: #fff; padding: 8px; font-size: 12px; }

/* Colour picker (spectrum.js) - matched to css/forms.css's own base-theme
   treatment: BOTH top corners square (not just the left one), since the
   popup is meant to sit flush directly under the full width of the
   swatch it drops down from, not look like it's floating half-detached.
   top:50px (not 42) restores the base theme's ~8px gap below the
   trigger - input height is the same 42px in both themes, so this is a
   directly comparable fix, not a guess. Left position intentionally NOT
   copied from base's `left: calc(100% - 200px)` - that's a hack tuned
   for base's own narrow-sidebar layout and could misplace the popup
   somewhere wrong in modern's different (wider) container widths without
   being able to see it render; flag if the popup's horizontal position
   still looks off after this. */
.sp-replacer { width: 100%; min-width: 200px; box-sizing: border-box; }
.sp-preview { width: calc(100% - 20px); overflow: hidden; box-sizing: border-box; }
.sp-container { border-radius: 0 0 var(--radius) var(--radius) !important; top: 50px !important; }
.sp-disabled { opacity: 0.35; }

/* UI Slider - dimensions restored to match css/forms.css's own base-theme
   values (the handle had shrunk to 44x14 here vs base's 50x30, less than
   half the height - "scaling wrong"). Colour tokens are kept as modern's
   own (brand-light-green track/border-strong tick lines instead of
   base's raw hex), only the sizing/position numbers are ported. */
.ui-slider { width: calc(100% - 50px); margin: 0 auto; top: 19px; background: var(--brand-light-green); border: 1px solid var(--main-color) !important; margin-bottom: 35px; border-radius: 4px; }
.ui-slider.hasTickmarks { top: 12px; }
.ui-slider .ui-slider-handle { width: 50px; height: 30px; padding: 6px 0; border-radius: var(--radius-sm); text-align: center; outline: 0 none !important; margin-left: -25px; font-size: 15px; margin-top: -10px; top: 0; background: var(--main-color); border: 1px solid var(--main-color-darker-1) !important; color: #ffffff; }
.ui-slider .ui-slider-handle.ui-state-active { background: var(--main-color-darker-1) !important; }
.ui-slider-horizontal { height: 10px; }
.ui-slider .ui-slider-range { opacity: 0.4; }
.sliderTickmark { box-sizing: border-box; height: 9px; float: left; border-right: 1px solid var(--border-strong); }
.sliderTickmark span { position: relative; left: 100%; top: 20px; font-size: 11px; white-space: nowrap; transform: translateX(-50%); display: inline-block; }
.sliderTickmarks .sliderTickmark:first-child,
.sliderTickmarks .sliderTickmark:last-of-type { border-right: 0; }
.sliderTickmarks .sliderTickmark:first-child { width: 0; }

/* File manager */
.file-manager-view {
    width: 100%;
    min-height: 400px;
    border: 1px solid var(--glass-border-color);
    border-radius: var(--radius-lg);
    overflow: clip;
    /* Same glassmorphism recipe as .filterBar - applied to the whole panel
       (not just the content grid) so it reads as one glass surface, with
       the breadcrumb bar's own background made transparent below so it
       doesn't paint over it. */
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, var(--glass-bg-opacity));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
}
/* .file-manager-breadcrumb (home icon + folder trail) is a real <button> in
   ajax/fileManager.php's markup, and modern has no <button> element reset
   anywhere (see the editor/accordion-header button fix above for the same
   root cause) - left unstyled it renders with raw browser button chrome
   sitting inside this flex bar. Given the compact icon-button treatment
   already used for the editor toolbar / accordion header buttons. */
.file-manager-breadcrumbs { width: 100%; padding: 8px 10px; display: flex; align-items: center; gap: 4px; flex-direction: row; background: transparent; border-bottom: 1px solid var(--glass-border-color); box-sizing: border-box; font-size: 13px; }
.file-manager-breadcrumb {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font: inherit;
    font-size: 12px;
    padding: 5px 10px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition), color var(--transition);
}
.file-manager-breadcrumb:hover { background: var(--surface); border-color: var(--border); color: var(--main-color); }
.file-manager-breadcrumb:last-child { color: var(--text-primary); font-weight: 600; }
.file-manager-access-type-readonly { width: 100%; padding: 8px 14px; background: #fff5f5; color: #e74c3c; font-size: 12px; box-sizing: border-box; }
.file-manager-content { display: grid; grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); gap: 8px; padding: 12px; box-sizing: border-box; }
/* .file-manager-btn is also shared by the "Create Folder"/"Add File"
   actions, which are real <button> elements too - reset font/background
   here so they match the <div>-based folder/file tiles instead of showing
   native button chrome. */
.file-manager-btn { position: relative; padding: 10px 8px; cursor: pointer; border-radius: var(--radius); text-align: center; color: var(--main-color) !important; border: 1px solid transparent; background: transparent; font: inherit; font-size: 12px; transition: background var(--transition), border-color var(--transition); }
.file-manager-btn:hover { background: var(--brand-light-green); border-color: var(--border); }
/* Also a real <button> (ajax/fileManager.php), same native-chrome gap as
   .file-manager-breadcrumb above - needs its own explicit reset since it's
   sized/positioned as a bare icon, not a padded button. */
.file-manager-delete-button {
    position: absolute;
    top: -4px;
    right: -4px;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    line-height: 1;
    color: #e74c3c;
    cursor: pointer;
    font-size: 18px;
    display: none;
}
.file-manager-btn:hover .file-manager-delete-button { display: block; }
.file-manager-btn-icon { width: 60px; height: 60px; font-size: 48px; display: flex; justify-content: center; align-items: center; margin: auto; }
.file-manager-btn-text { display: block; font-size: 11px; word-break: break-word; margin-top: 4px; }
.file-manager-text-input { display: none; width: 100% !important; height: fit-content !important; padding: 0 4px !important; border: 0 !important; font-size: 11px !important; margin: 0 !important; text-align: center !important; position: relative; box-sizing: border-box !important; }
.file-upload-content { width: 100%; padding: 20px; box-sizing: border-box; }
.file-upload-content .dropzoneStyle { min-height: 180px; align-content: center; }
.file-manager-drop-active, .file-manager-can-drop { border: 1px dashed var(--main-color) !important; }
.file-manager-can-drop { background: var(--brand-light-green); }

/* ============================================================
   CALENDAR MODULE (classes/core/class.Calendar.php, css/calendar.css)
   Not included anywhere on modern before this pass - a full gap, same as
   editor.css was. calendar.css carries structural/interactive CSS the
   widget depends on (the month/year label's hover-to-reveal dropdown is a
   plain display:none / :hover toggle, no JS show/hide involved - drop the
   include and the dropdown simply never appears) alongside its own bold
   solid-colour look, so it's pulled in directly here first (same pattern
   as editor.css) and then reskinned below to match modern's neutral
   surface/border language + --main-color accents (the same language the
   datepicker and accordion header already use) instead of the
   base/gardenWaste version's solid --main-color-shaded block. All the
   original layout numbers (padding, cell heights, dropdown width) are
   left untouched - only colour/background/border/radius/transition
   properties are overridden, per this project's "recolor, don't resize"
   rule for CSS work done without a way to render the page locally. Not
   yet verified live - expect a follow-up round once it's been seen.
   ============================================================ */
.calendar {
    background: var(--main-color);
    border-radius: var(--alt-radius);
    width: 100%;
    flex: 1 1 500px;
}

.calendar .calendarNavigation {
    display: flex;
    flex-flow: row nowrap;
    color: #FFFFFF;
    font-size: 20px;
    width: 100%;
}

.calendar .calendarNavBtn {
    flex: 0 0 auto;
    padding: 20px;
    text-align: center;
    cursor: pointer;
}

.calendar .calendarHeader {
    flex: 1 1 500px;
    text-align: center;
    padding: 20px 10px;
    text-transform: uppercase;
}

.calendar .calendarHeader .monthText, .calendar .calendarHeader .yearText {
    cursor: pointer;
    position: relative;
}

.calendar .calendarHeader .monthText .monthSelector, .calendar .calendarHeader .yearText .yearSelector {
    display: none;
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    width: 100px;
    background: var(--main-color);
    border: 1px solid #FFFFFF;
    z-index: 101;
}

.calendar .calendarHeader .monthText:hover .monthSelector, .calendar .calendarHeader .yearText:hover .yearSelector {
    display: inline-block;
}

.calendar .calendarHeader .monthText .monthSelector ol, .calendar .calendarHeader .yearText .yearSelector ol {
    list-style: none;
    padding: 0px;
    margin: 0px;
}

.calendar .calendarHeader .monthText .monthSelector ol li, .calendar .calendarHeader .yearText .yearSelector ol li {
    padding: 5px;
}

.calendar .calendarHeader .monthText .monthSelector ol li:hover, .calendar .calendarHeader .yearText .yearSelector ol li:hover {
    background: var(--main-color-darker-1);
}

.calendar .calendarHeader .monthText .monthSelector ol li.curMonth, .calendar .calendarHeader .yearText .yearSelector ol li.curYear {
    background: var(--main-color-darker-2);
}

.calendar .calendarContainer {
    padding: 0px 10px 10px 10px;
    position: relative;
    min-height: 700px;
}

.calendar .calendarLoadingOverlay {
    background: var(--main-color-darker-2);
    opacity: 0.75;
    position: absolute;
    width: calc(100% - 20px);
    bottom: 10px;
    top: 0px;
    z-index: 99;
}

.calendar .calendarLoadingOverlaySpinner {
    position: absolute;
    color: var(--main-color-lighter-1);
    width: 50px;
    height: 50px;
    font-size: 50px;
    line-height: 50px;
    z-index: 100;
    top: 50%;
    left: 50%;
    margin: -25px 0 0 -25px;
    animation: spin 3s linear infinite;
}

.calendar table {
    width: 100%;
    border: 1px solid #999999;
    table-layout: fixed;
    border-collapse: collapse;
}

.calendar table tr {
}

.calendar table th {
    background: var(--main-color-darker-2);
    border: 1px solid var(--main-color-darker-3);
}

.calendar table td {
    background: var(--main-color-lighter-4);
    border: 1px solid var(--main-color-darker-3);
    height: 150px;
    padding: 5px;
    vertical-align: top;
    text-align: left;
}

.calendar table td:hover {
    background: var(--main-color-lighter-3);
}

.calendar table td.blank {
    background: var(--main-color-darker-1);
}

.calendar table td.pastDay {
    background: var(--main-color-lighter-2-5);
    color: #FFFFFF;
}

.calendar table td.disabledDay {
    background: var(--main-color-lighter-2);
    color: #FFFFFF;
}


.calendar table td .dayNum {
    color: var(--main-color-darker-3);
    margin-bottom: 5px;
}

.calendar table td a {
    color: var(--main-color-darker-3);
    float: right;
}
.calendar table td a:hover {
    color: var(--main-color-darker-4);
}

.calendar .event {
    background-color: var(--main-color);
    width: 100%;
    color: #FFFFFF;
    padding: 5px;
    margin-bottom: 5px;
    border-radius: var(--alt-radius);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    height: 30px;
    position: relative;
}

.calendar .event:hover {
    background-image: linear-gradient(rgb(0 0 0/20%) 0 0);
}

.calendar .blankEvent {
    width: 100%;
    padding: 5px;
    margin-bottom: 5px;
    border-radius: var(--alt-radius);
    white-space: pre-wrap;
    overflow: hidden;
    text-overflow: ellipsis;
    height: 30px;
}

.calendar .eventBlock {
    background-color: var(--main-color);
    width: calc(100% + 10px);
    margin-left: -5px;
    margin-right: -5px;
    color: #FFFFFF;
    padding: 5px;
    margin-bottom: 5px;
    border-radius: 0px;
    height: 30px;
    position: relative;
}

.calendar .eventBlock:hover {
    background-image: linear-gradient(rgb(0 0 0/20%) 0 0);
}

.calendar .eventBlock.hovered {
    background-image: linear-gradient(rgb(0 0 0/20%) 0 0);
}

.calendar .eventBlockStart {
    width: calc(100% + 5px);
    margin-left: 0px;
    border-top-left-radius: var(--alt-radius);
    border-bottom-left-radius: var(--alt-radius);
}

.calendar .eventBlockEnd {
    width: calc(100% + 5px);
    margin-right: 0px;
    border-top-right-radius: var(--alt-radius);
    border-bottom-right-radius: var(--alt-radius);
}

.calendar .eventName {
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    position: absolute;
    z-index: 1;
    height: 20px;
    pointer-events: none;
    width: 100%;
}

.calendar .hasFunction {
    cursor: pointer;
}

.calendar .hiddenEventsButton {
    margin-bottom: 0px;
}

.calendar .hiddenEvents {
    display: none;
}

.calendar .holiday {
    height: 15px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 10px
}
/* Same glassmorphism recipe as .filterBar/.file-manager-view - applied to
   the outer panel; the grid's own cell backgrounds below are switched from
   opaque surface tokens to translucent overlays so the glass shows through
   the whole widget rather than being hidden behind a solid table. The nav
   bar keeps its solid --main-color fill, matching the datepicker's
   solid-header-over-glass-body pattern. */
.calendar {
    border: 1px solid var(--glass-border-color);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, var(--glass-bg-opacity));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
}

.calendar .calendarNavigation { background: var(--main-color); }
.calendar .calendarNavBtn { transition: background var(--transition); }
.calendar .calendarNavBtn:hover { background: rgba(255, 255, 255, 0.15); }

/* Month/year hover dropdown - jQuery-free, pure CSS :hover reveal (see
   calendar.css) so it needed the same "real popup" treatment as the
   datepicker/select menus: surface background + border + shadow instead
   of the base template's solid-on-solid main-color-on-main-color panel. */
.calendar .calendarHeader .monthText .monthSelector,
.calendar .calendarHeader .yearText .yearSelector {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15);
    color: var(--text-primary);
    overflow: hidden;
}
.calendar .calendarHeader .monthText .monthSelector ol li,
.calendar .calendarHeader .yearText .yearSelector ol li { transition: background var(--transition); }
.calendar .calendarHeader .monthText .monthSelector ol li:hover,
.calendar .calendarHeader .yearText .yearSelector ol li:hover { background: var(--brand-light-green); }
.calendar .calendarHeader .monthText .monthSelector ol li.curMonth,
.calendar .calendarHeader .yearText .yearSelector ol li.curYear { background: var(--main-color); color: #ffffff; }

/* Loading overlay - matches the app-wide #loadingOverlay treatment
   (translucent white + blur) rather than the base template's solid dark
   tint, so it reads as "this widget" rather than a full-page block. */
.calendar .calendarLoadingOverlay {
    background: rgba(255, 255, 255, 0.75);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    opacity: 1;
}
.calendar .calendarLoadingOverlaySpinner { color: var(--main-color); }

.calendar table { border: 1px solid var(--glass-border-color); }
/* The generic tr rule (zebra-stripe backgrounds + its own backdrop-filter
   blur, used for regular data tables) would otherwise double up against
   the .calendar container's own glass blur and paint stripes over it -
   turned off here so the container is the only source of the glass
   effect, same fix already applied to .ui-datepicker tr. */
.calendar table tr {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}
.calendar table tr:nth-child(even),
.calendar table tr:nth-child(odd),
.calendar table tr:hover,
.calendar table tr.evenRow,
.calendar table tr.oddRow { background: none; }
.calendar table th { background: rgba(255, 255, 255, 0.25); border: 1px solid var(--glass-border-color); color: var(--text-secondary); }
.calendar table td { height: 152px; background: transparent; border: 1px solid var(--glass-border-color); transition: background var(--transition); }
.calendar table td:hover { background: var(--brand-light-green); }
.calendar table td.blank { background: rgba(0, 0, 0, 0.04); }
.calendar table td.pastDay { background: rgba(0, 0, 0, 0.04); color: var(--text-muted); }
.calendar table td.disabledDay { background: rgba(0, 0, 0, 0.04); color: var(--text-muted); }
.calendar table td .dayNum { color: var(--text-primary); }
.calendar table td a { color: var(--main-color); }
.calendar table td a:hover { color: var(--main-color-darker-1); }

/* Event pills. classes/core/class.Calendar.php can set a per-event inline
   style="background-color: ...; color: ...;" (custom event colour, with a
   WCAG-luminance-based text colour computed server-side - see
   Calendar::getContrastTextColor()) - a class rule can't out-specificity an
   inline style, so background-color/color stay exactly as the base
   template always had them (event colour still wins), and the glass
   treatment is layered on separately via properties inline never touches:
   background-image (a translucent sheen - inline only sets background-
   *color*, so this longhand survives untouched underneath it),
   backdrop-filter (put directly on the pill itself, not a separate
   overlay - an earlier ::before-overlay version blurred the "+x Events"
   button's raw text too, because that text has no .eventName wrapper/
   z-index to stack above a positioned overlay; backdrop-filter on the
   pill's own box only blurs what's behind the box, never the box's own
   foreground content, so it can't blur any of the pill's own text), and
   opacity (genuine see-through - background-color/text/border/blur all
   composite against the day cell behind at the same alpha, which an
   inline colour can't defeat since it doesn't touch opacity). Vertical
   (180deg, not the shared --glass-tint-angle diagonal) because stacked
   pills in the same day cell sit directly above/below each other, and a
   diagonal sheen broke continuity right at that boundary. */
.calendar .event,
.calendar .eventBlock {
    background-color: var(--main-color);
    background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.44) 0%, rgba(255, 255, 255, 0.04) 100%);
    z-index: unset;
}
.calendar .eventName { width: calc(100% - 10px); }
/* calendar.css's :hover/.hovered rules set background-image to a flat dark
   overlay (linear-gradient(rgb(0 0 0/20%) 0 0)) to darken the pill on hover
   - background-image is a single property, so that completely replaced the
   sheen gradient above instead of adding to it (and won on specificity,
   since :hover/.hovered add an extra selector). Restated here with both
   gradients stacked in one background-image (comma-separated layers paint
   front-to-back, so the darken tint listed first sits on top of the sheen)
   so hovering darkens without losing the glass sheen underneath. */
.calendar .event:hover,
.calendar .eventBlock:hover,
.calendar .eventBlock.hovered {
    background-image: linear-gradient(rgb(0 0 0/20%) 0 0), linear-gradient(180deg, rgba(255, 255, 255, 0.44) 0%, rgba(255, 255, 255, 0.04) 100%);
}
.calendar .event { border-radius: var(--radius-sm); }
.calendar .blankEvent { border-radius: var(--radius-sm); }
.calendar .eventBlock {
    /* calendar.css's own +10px was 1px short of fully bridging the cell
       padding/border seam between days - widened to close the visible gap
       reported between multi-day event segments. */
    width: calc(100% + 11px);
}
.calendar .eventBlockStart {
    border-top-left-radius: var(--radius-sm);
    border-bottom-left-radius: var(--radius-sm);
    width: calc(100% + 6px);
    z-index: 1;
}
.calendar .eventBlockEnd {
    border-top-right-radius: var(--radius-sm);
    border-bottom-right-radius: var(--radius-sm);
    /* Must be restated explicitly, not just "left alone" - .eventBlock's
       width: calc(100% + 11px) above is equal-specificity and comes first
       in source order, but calendar.css's own .eventBlockEnd rule (which
       would otherwise win this by appearing later) lives inside the
       included file above, so simply not touching width here left
       .eventBlock's 11px in effect instead of falling back to it. End is
       meant to stop short of the next cell rather than bridge into it, so
       this must stay at the original, unwidened +5px. */
    width: calc(100% + 5px);
}

/* Font awesome picker */
.fontawesomeContainer { width: 100%; }
.fontawesomeSearchBar { width: 100%; }
.fontawesomeSearchResults { width: 100%; min-height: 240px; max-height: 240px; overflow-y: scroll; border: 1px solid var(--border); border-radius: var(--radius); margin-top: 4px; }
.fontawesomePreview { width: 130px; margin: 4px; padding: 6px; float: left; min-height: 56px; border-radius: var(--radius); }
.fontawesomePreview:hover { border: 1px solid var(--main-color); background: var(--brand-light-green); color: var(--main-color); cursor: pointer; }
.activeFont { color: #fff; border: 1px solid var(--main-color); border-radius: var(--radius); background: var(--main-color); }

/* SELECT2 overrides */
.select2.select2-container {
    width: 100%;
    height: 42px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    color: var(--text-primary);
    min-width: 160px;
}
.select2.select2-container .select2-selection {
    border: 0;
    border-radius: var(--radius);
    height: 40px;
    outline: none !important;
    transition: all var(--transition);
    text-align: left;
}
.select2.select2-container .select2-selection .select2-selection__rendered {
    color: var(--text-primary);
    padding: 0 32px 0 12px;
    line-height: 40px;
    height: 40px;
}
.select2.select2-container .select2-selection .select2-selection__arrow {
    height: 100%;
    width: 28px;
    color: #fff;
    top: 0px;
    border: 0px;
    right: 0px;
    border-radius: 0px 5px 5px 0px;
    /* Overrides select2.css's own `background: lightgrey;` on this same
       selector - ours wins on specificity (4 classes vs vendor's 3), no
       !important needed. */
    background: var(--main-color);
}
/* Select2's default theme draws the arrow as a CSS border-triangle on an
   empty <b> element (no icon font involved), so recoloring it means
   changing this border-color, not the .select2-selection__arrow's own
   (mostly cosmetic/unused) color property above. */
.select2-container--default .select2-selection--single .select2-selection__arrow b {
    border-color: #fff transparent transparent transparent !important;
}
/* select2.css has a SEPARATE, more specific rule for the open state that
   flips BOTH border-color (bottom edge instead of top) AND border-width
   (0 4px 5px 4px instead of 5px 4px 0 4px) to point the triangle upward.
   The rule above only overrides border-color (with !important, so it
   always wins regardless of state) and never touches border-width - so
   while open, the top edge it colours has 0 width from vendor's rule,
   and the bottom edge vendor's own open rule would colour gets forced
   back to transparent by that !important. Both possible visible edges
   end up invisible, which is why the icon disappeared whenever the
   dropdown opened. Restating color AND width together for the open
   state renders a proper upward-pointing white triangle instead. */
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
    border-color: transparent transparent #fff transparent !important;
    border-width: 0 4px 5px 4px !important;
}
.select2.select2-container.select2-container--open .select2-selection.select2-selection--single { background: #fafff7; }
.select2-container .select2-dropdown { background: transparent; border: none; margin-top: -3px; }
.select2-container .select2-dropdown .select2-search { padding: 0; }
.select2-container .select2-dropdown .select2-search input {
    outline: none !important;
    border: 1px solid var(--main-color) !important;
    border-bottom: none !important;
    padding: 10px 12px !important;
    height: 42px;
    color: var(--text-primary);
    border-radius: var(--radius) var(--radius) 0 0;
}
.select2-container .select2-dropdown .select2-results ul {
    background: var(--surface);
    border: 1px solid var(--main-color);
    max-height: 320px;
    border-radius: var(--alt-radius-bottom);
    box-shadow: var(--shadow-md);
}
.select2-container .select2-dropdown .select2-results ul .select2-results__option {
    background: var(--surface);
    padding: 10px 12px !important;
    color: var(--text-primary);
    font-size: 13px;
}
.select2-container .select2-dropdown .select2-results ul .select2-results__option--highlighted[aria-selected] {
    background: var(--brand-light-green);
    color: var(--main-color);
}
/* Multi-select needs to GROW with wrapped chip rows, not stay pinned to
   the single-select height. Both .select2.select2-container (height:42px
   above) and .select2.select2-container .select2-selection (height:40px
   above, matched here since select2's own markup always carries both
   select2-selection and select2-selection--multiple on the same
   element) fix a flat height meant for a single line of text, and
   select2.css's own base (non --default) rule leaves
   .select2-selection__rendered's overflow:hidden un-reset - so any chips
   that wrapped past the first row were silently clipped instead of
   growing the box. "Scaling and padding... messed up" once more than a
   couple of items were selected. */
.select2.select2-container:has(.select2-selection--multiple) {
    height: auto;
    min-height: 42px;
}
.select2.select2-container .select2-selection.select2-selection--multiple {
    height: auto;
    min-height: 40px;
}
.select2.select2-container .select2-selection--multiple .select2-selection__rendered {
    display: block;
    height: auto;
    min-height: 38px;
    overflow: visible;
    white-space: normal;
    /* No top padding - each chip (and the search field below) already
       carries its own margin-top:5px (vendor default, matched below),
       which supplies a consistent gap above every row including the
       first, the same way it already spaces row-to-row. Bottom padding
       restates that same 5px so the last row gets an equivalent gap
       below it too, since nothing else provides one there. */
    padding: 0 12px 5px;
    line-height: normal;
    border-radius: var(--radius);
}
.select2.select2-container .select2-selection--multiple .select2-selection__choice {
    background: var(--main-color-lighter-4);
    border: 1px solid var(--main-color);
    border-radius: var(--radius-sm);
    margin: 5px 8px 0 -4px;
    padding: 0 10px 0 28px;
    height: 28px;
    line-height: 28px;
    font-size: 13px;
    position: relative;
    color: var(--main-color);
}
/* flex centering instead of a hardcoded top/left inset - robust
   regardless of the exact glyph metrics, same reasoning as the
   .squaredCheck tick-alignment fix elsewhere in this file (a fixed
   offset tuned for one size silently drifts off-center the next time
   the pill's own height changes). */
.select2.select2-container .select2-selection--multiple .select2-selection__choice .select2-selection__choice__remove {
    position: absolute;
    top: 0; left: 0;
    height: 100%; width: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    color: var(--main-color);
    font-weight: bold;
}
.select2-container--default.select2-container--focus .select2-selection--multiple { border: none !important; }
.select2-search { padding: 0 !important; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove { border: none !important; }
/* margin-top left at select2.css's own default (5px, matching the chips'
   own margin-top:5px for a consistent row rhythm) - a padding-top and a
   1px-off margin-top were stacked on top of that here previously (14px
   combined instead of 5px), which went unnoticed while the container
   was still a fixed height with overflow:hidden clipping the excess, but
   pushed the search row down and inflated the container once that was
   fixed to grow with content.

   height/padding/border/background are the REAL reason the field never
   fit right: this is a real <input type="search">, and modern has a
   generic app-wide input[type="search"] rule (height:42px; padding:0
   12px; border:1px solid var(--border-strong); background:var(--surface);
   ...) that was never overridden here - select2.css's own
   .select2-search--inline rule only resets background/border/outline/
   box-shadow, not height or padding, so those two fell straight through
   from the generic rule unopposed: a 42px-tall bordered input was
   rendering inside a row of 28px chips. Overriding all of it here (this
   selector's specificity comfortably beats the generic one) sizes it to
   match the chip row instead. */
.select2.select2-container .select2-selection--multiple .select2-search--inline .select2-search__field {
    width: 100% !important;
    height: 28px;
    line-height: 28px;
    padding: 0 !important;
    border: none !important;
    background: transparent !important;
    color: var(--text-primary);
    font-size: 13px;
}
.filterBar .select2.select2-container .select2-selection__rendered { line-height: 32px; }
.select2InPopup { z-index: 10000; }
.fontawsomePlaceholder { font-family: Arial, FontAwesome !important; }
.fontawesomeSearchResults { margin-top: 4px; border-radius: var(--radius); border: 1px solid var(--border); }
.dialogSelect { margin-left: -1px; }
.select2 #content ul li { padding: 0; }
.select2-results__options { z-index: 9999; }


/* ============================================================
   TABLES
   ============================================================ */
.tableContainer {
    width: 100%;
    overflow-x: auto;
    position: relative;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    background: none;
}

/* Scroll fade overlays — applied to a JS-injected wrapper */
.tableContainerWrap {
    position: relative;
}
.tableContainerWrap::before,
.tableContainerWrap::after {
    content: '';
    position: absolute;
    top: 0; bottom: 0;
    width: 48px;
    pointer-events: none;
    z-index: 2;
    opacity: 0;
    transition: opacity 0.2s ease;
    border-radius: var(--radius-lg);
}
.tableContainerWrap::before {
    left: 0;
    background: linear-gradient(to right, rgba(0,0,0,0.07), transparent);
}
.tableContainerWrap::after {
    right: 0;
    background: linear-gradient(to left, rgba(0,0,0,0.07), transparent);
}
.tableContainerWrap.fade-left::before  { opacity: 1; }
.tableContainerWrap.fade-right::after  { opacity: 1; }

table {
    border-collapse: collapse;
    border-spacing: 0;
    width: 100%;
    font-size: 13px;
}

/* z-index is required, not decorative, here: the generic `tr` rule below
   gives every row its own backdrop-filter (for the app-wide glass look on
   regular tables), and backdrop-filter creates a stacking context even on
   a position:static element - so every tbody row is implicitly promoted
   to the same "z-index:0" stacking level as this absolutely-positioned
   clone. At equal stacking level, later DOM order wins, and the clone is
   prependTo()'d (so it's earliest in the table's children) - without an
   explicit z-index the tbody rows painted after it in the stylesheet's
   default ordering, hiding the clone underneath them. */
/* table-layout: fixed so the browser strictly honours the individually-set
   per-column widths (set in JS, matching the real header's cell widths)
   instead of re-auto-sizing them to fit the clone's own box - without this
   the columns can drift out of alignment with the real table underneath,
   especially on a wide, horizontally-scrolling table. */
thead.clone { display: table; table-layout: fixed; width: 100%; position: absolute; left: 0; top: 0; z-index: 5; background: var(--surface); }

th {
    padding: 9px 12px;
    background: #f7f8f6;
    color: var(--text-secondary);
    border-bottom: 2px solid var(--border);
    border-right: 1px solid var(--border);
    vertical-align: middle;
    font-weight: 600;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
    text-align: left;
}
th:last-child { border-right: none; }
th a { color: var(--text-secondary); }

td {
    padding: 9px 12px;
    text-align: left;
    border-bottom: 1px solid var(--border);
    border-right: 1px solid var(--border);
    vertical-align: middle;
    white-space: nowrap;
    color: var(--text-primary);
}
td:last-child { border-right: none; }
td .text { cursor: text; }

.optionsColumn { width: 1%; white-space: nowrap; }

tr {
    transition: background var(--transition);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
}
tr:last-child td { border-bottom: none; }
tr:nth-child(even) { background: #ffffffb5; }
tr:nth-child(odd)  { background: #f9faf7b5; }
tr.evenRow { background: #ffffffb5; }
tr.oddRow  { background: #f9faf7b5; }
tr:hover   { background: var(--brand-light-green); }

/* .rowSpanHighlighting (any table using <td rowspan="..."> - e.g.
   class.Table.php's Multidimensional Data Table example) needs the generic
   tr rule's backdrop-filter turned off: a rowspanned cell only belongs to
   the <tr> it starts in, but its rendered box overlaps the following
   sibling rows - and backdrop-filter creates a stacking context on an
   element even without position/z-index, promoting every plain in-flow tr
   to the same stacking level. At that level, later DOM-order rows win the
   tie and paint over the earlier row, blurring the rowspanned cell
   wherever a later row's box overlaps it - "the first column looks
   blurry". Same root cause already hit and fixed for .ui-datepicker tr and
   .calendar table tr. Only backdrop-filter needs removing here, not the
   background - plain background-color doesn't create a stacking context,
   so it was never part of the bug, and removing it too just left the rows
   with no background at all. (.no-table-alt is unrelated - it opts a table
   out of the small-screen card layout, not row striping - don't touch it
   for this.) */
.rowSpanHighlighting tr {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}
/* Restore the glass look at the container level instead of per-row - one
   single stacking context for the whole table, so it can't create the
   same later-row-paints-over-earlier-rowspanned-cell conflict the per-row
   version did. Blur only, no background tint here: the rows still carry
   their own semi-transparent zebra background (tr:nth-child above), which
   already supplies the translucent white wash a normal table's per-row
   backdrop-filter + own background combo gives it. Adding the container's
   own white gradient tint on top of that stacked a second translucent
   layer, compounding into something visibly more opaque/less see-through
   than a normal table's single layer. */
.tableContainer:has(.rowSpanHighlighting) {
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
}

.clickableRow { cursor: pointer; }

.fa-sort, .fa-sort-down, .fa-sort-up { margin-left: 4px; opacity: 0.4; }
th:hover .fa-sort { opacity: 0.8; }

.rowHighlight         { background: var(--main-color-lighter-5) !important; color: var(--main-color); }
.rowHighlightSelected { background: var(--main-color-lighter-3) !important; color: var(--text-primary); }
.leftAlignData td     { text-align: left; }

/* Info table (key-value) */
.infoTable { font-size: 13px; }
.infoTable th {
    padding: 7px 12px;
    background: var(--surface-alt);
    color: var(--text-secondary);
    border: 0;
    border-right: 2px solid var(--border);
    vertical-align: top;
    font-weight: 600;
    text-align: right;
    white-space: nowrap;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
.infoTable td {
    width: 100%;
    padding: 7px 12px;
    background: none;
    border: 0;
    color: var(--text-primary);
    vertical-align: middle;
    text-align: left;
}
.infoTable tr          { border-bottom: 1px solid var(--border); }
/* Zebra-stripe the normal data rows (same tint tokens as the app's generic
   tr rule, for consistency) but not a .header divider row - :has() lets us
   exclude those without needing a separate class on the <tr> itself. */
.infoTable tr:nth-child(even):not(:has(.header)) { background: #ffffffb5; }
.infoTable tr:nth-child(odd):not(:has(.header))  { background: #f9faf7b5; }
.infoTable tr:hover:not(:has(.header)) { background: var(--brand-light-green); }
/* Styled to match .infoTable th (the row-label cells in this same table),
   not the generic app-wide <th>, since a .header row is a section divider
   within an info table specifically - same surface-alt/uppercase treatment,
   centred instead of right-aligned since it spans the full width. */
.infoTable td.header {
    background: var(--surface-alt);
    color: var(--text-secondary);
    font-weight: 600;
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    font-size: 12px;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    padding: 6px 12px;
}
.infoTable tr:first-child { border-top: 1px solid var(--border); }
.infoTable tr:last-child  { border-bottom: 1px solid var(--border); }
.infoTable.noBorder tr:first-child { border-top: 0; }
.infoTable.noBorder tr:last-child  { border-bottom: 0; }

/* Row context menu */
.rowContextMenu {
    position: absolute;
    display: none;
    min-width: 180px;
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-md);
    border-radius: var(--radius-lg);
    overflow: clip;
    z-index: 500;
    padding: 4px;
}
.rowContextMenu button {
    display: block;
    width: 100%;
    padding: 8px 12px;
    border: 0;
    background: none;
    text-align: left;
    cursor: pointer;
    font-size: 13px;
    color: var(--text-primary);
    border-radius: var(--radius-sm);
    font-family: inherit;
}
.rowContextMenu button:hover { background: var(--brand-light-green); color: var(--main-color); }

/* Mobile */
@media only screen and (max-width: 600px) {
    table, table.infoTable { font-size: 11px; }
    td, th { padding: 6px 8px; }
}


/* ============================================================
   PAGINATION
   ============================================================ */
#pagination_range {
    margin: 0 auto 8px;
    text-align: center;
    font-size: 12px;
    color: var(--text-muted);
}

.pagination_nav {
    width: 100%;
    text-align: center;
    margin: 0;
    padding-left: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 3px;
}

.pagination_nav li {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    height: 30px;
    padding: 0 6px !important;
    border-radius: var(--radius);
    font-size: 13px;
    font-weight: 500;
    color: var(--text-secondary);
    border: 1px solid var(--border);
    background: var(--surface);
    transition: background var(--transition), color var(--transition), border-color var(--transition);
    cursor: pointer;
    user-select: none;
}

.pagination_nav li:hover {
    background: var(--brand-light-green);
    border-color: var(--main-color);
    color: var(--main-color);
}

.pagination_nav .current_page {
    background: var(--main-color);
    border-color: var(--main-color-darker-1);
    color: #ffffff;
    font-weight: 600;
    cursor: default;
    box-shadow: 0 1px 3px rgba(var(--main-color-rgb), 0.30);
}
.pagination_nav .current_page:hover { background: var(--main-color); color: #ffffff; border-color: var(--main-color-darker-1); }

.pagination_nav .disabled_page_nav {
    cursor: default;
    color: var(--text-muted);
    background: var(--surface-alt);
    border-color: var(--border);
}
.pagination_nav .disabled_page_nav:hover { background: var(--surface-alt); color: var(--text-muted); border-color: var(--border); }

.paginate {
    padding: 8px 0;
    width: 100%;
    text-align: right;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    font-size: 12px;
    color: var(--text-secondary);
}

.paginate select {
    border: 1px solid var(--border-strong);
    padding: 4px 8px;
    border-radius: var(--radius);
    color: var(--text-primary);
    background: var(--surface);
    font-size: 12px;
    height: auto;
    width: auto;
    cursor: pointer;
}


/* ============================================================
   BADGES & STATUS
   ============================================================ */
.badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 20px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
}
.badge-green,  .badge-success { background: #eaf7ee; color: #2a6534; }
.badge-red,    .badge-danger  { background: #fff0f0; color: #c0392b; }
.badge-orange, .badge-warning { background: var(--brand-orange-bg); color: #7a3c00; }
.badge-blue,   .badge-info    { background: #eaf3ff; color: #1a5fa8; }
.badge-gray                   { background: var(--brand-light-green); color: var(--main-color-darker-2); }


/* ============================================================
   ALERTS
   ============================================================ */
.alert {
    padding: 12px 16px;
    border-radius: var(--radius);
    font-size: 13px;
    margin-bottom: 12px;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    border: 1px solid;
}
.alert-success { background: #f3faf5; color: #2a6534; border-color: #b7dfbf; }
.alert-error,
.alert-danger   { background: #fff5f5; color: #c0392b; border-color: #f5b7b1; }
.alert-warning  { background: var(--brand-orange-bg); color: #7a3c00; border-color: #fac36a; }
.alert-info     { background: #eaf3ff; color: #1a5fa8; border-color: #a9cdf0; }


/* ============================================================
   CONTENT BLOCK (collapsible section panel - pages/examples.php,
   helpers/phpFunctions.php's toggleSectionDisplayIcon()/sectionDisplayClass()/
   sectionDisplay()). Not styled anywhere on modern before this pass - a
   full gap, same as editor.css/calendar.css were. base/gardenWaste render
   it as a solid uppercase --main-color-tinted header bar
   (css/gardenWaste/template.css); redone here with modern's neutral card
   language (surface/border/radius tokens) instead of copying that look
   verbatim, consistent with the accordion/editor/file-manager already
   redone the same way this session.
   ============================================================ */
.contentBlockContainer { width: 100%; box-sizing: border-box; }

.contentBlockHeader {
    display: flex;
    flex-flow: row;
    align-items: center;
    gap: 8px;
    width: 100%;
    box-sizing: border-box;
    margin: 0;
    padding: 10px 14px;
    background: var(--surface-alt);
    border: 1px solid var(--glass-border-color);
    border-bottom: none;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    color: var(--text-primary);
    font-size: 14px;
    font-weight: 600;
}
.sectionTitle { flex: 1 1 auto; }
.right-links { flex: 0 0 auto; display: flex; align-items: center; gap: 4px; }
/* toggleSectionDisplayIcon() wraps a bare <i class="displayIcon ..."> in an
   <a> with no class of its own - sized/coloured on the anchor itself
   (matching the compact icon-button pattern used for the editor toolbar /
   accordion header buttons / file-manager breadcrumbs elsewhere in this
   file), so the icon just inherits colour via currentColor. */
.contentBlockHeader .right-links a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    transition: background var(--transition), color var(--transition);
}
.contentBlockHeader .right-links a:hover { background: var(--surface); color: var(--main-color); }

/* Same glassmorphism recipe as .filterBar/.file-manager-view/.calendar -
   header above stays a solid --surface-alt bar, matching the established
   "solid header over glass body" composition used elsewhere. */
.contentBlock {
    padding: 14px;
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, var(--glass-bg-opacity));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border-color);
    border-top: none;
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

.contentHiddenNotification {
    padding: 10px 14px;
    margin-bottom: 10px;
    border-radius: var(--radius);
    background: var(--brand-orange-bg);
    color: #7a3c00;
    border: 1px solid #fac36a;
    font-size: 13px;
}

/* Icon-count summary row (comments/flags/files/warnings above a content
   block) */
.iconContainer {
    width: 100%;
    box-sizing: border-box;
    display: flex;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 16px;
    padding: 8px 14px;
    margin-bottom: 10px;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.iconCount {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text-secondary);
    font-size: 13px;
    cursor: pointer;
}
.iconCount .icon { color: var(--main-color); }


/* ============================================================
   DIALOGS / jQuery UI
   ============================================================ */

/* Sit above the sidebar (z-index 300) and top-bar (z-index 200) */
.ui-dialog         { z-index: 600 !important; }
.ui-widget-overlay { z-index: 599 !important; background: rgba(0,0,0,0.35) !important; }

/* No close button — dialogs always use the button pane */
.ui-dialog-titlebar-close { display: none !important; }

.ui-dialog {
    position: fixed !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    margin: 0 !important;
    border: 1px solid var(--border) !important;
    border-radius: var(--radius-xl) !important;
    box-shadow: var(--shadow-lg) !important;
    padding: 0 !important;
    font-family: inherit !important;
    font-size: 13px !important;
}
.ui-dialog-titlebar {
    background: var(--surface) !important;
    border: none !important;
    border-bottom: 1px solid var(--border) !important;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0 !important;
    padding: 14px 18px !important;
    font-size: 14px !important;
    font-weight: 600 !important;
    color: var(--text-primary) !important;
}
.ui-dialog-content { padding: 18px !important; background: var(--surface) !important; font-family: inherit !important; font-size: 13px !important; }
.ui-dialog-buttonpane { background: var(--surface-alt) !important; border-top: 1px solid var(--border) !important; padding: 12px 18px !important; border-radius: 0 0 var(--radius-xl) var(--radius-xl) !important; }
.ui-dialog-buttonset button {
    padding: 7px 14px;
    border-radius: var(--radius);
    font-size: 13px;
    font-weight: 500;
    border: 1px solid var(--border-strong);
    background: var(--surface);
    color: var(--text-primary);
    cursor: pointer;
    font-family: inherit;
    transition: background var(--transition);
    margin-left: 6px;
}
.ui-dialog-buttonset button:hover { background: var(--surface-alt); }
.ui-dialog-buttonset button:first-child { background: var(--main-color); color: #fff; border-color: var(--main-color-darker-1); }
.ui-dialog-buttonset button:first-child:hover { background: var(--main-color-darker-1); }
/* Colours/typography only - deliberately leaves every jquery-ui default
   dimension, padding and positioning value (17em width, .2em paddings, the
   1.8em prev/next boxes, em-based table sizing) completely untouched. That
   default layout math is what makes everything fit inside the popup;
   overriding it with fixed pixel widths (tried previously) broke the fit. */
.ui-datepicker {
    z-index: 610 !important;
    border: 1px solid var(--glass-border-color) !important;
    border-radius: var(--radius-lg) !important;
    box-shadow: var(--shadow-md) !important;
    font-family: inherit !important;
    /* jquery-ui's own default padding (.2em .2em 0) sets bottom to 0, relying
       on the table's own bottom margin instead - explicit and equal on all
       4 sides here so the box doesn't look lopsided. */
    padding: 10px !important;
    /* Same glass background as .filterBar */
    background:
        linear-gradient(var(--glass-tint-angle), var(--glass-tint-start) 0%, var(--glass-tint-end) 100%),
        rgba(255, 255, 255, var(--glass-bg-opacity));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
}
/* The table's own bottom margin would otherwise stack on top of the
   container's padding above, making the bottom gap bigger than the sides. */
.ui-datepicker table { margin: 0; }
/* Month header - solid brand colour, opaque over the glass background above
   it. Padding is left at jquery-ui's own default so the prev/next buttons
   (positioned by fixed top/left/right offsets, unaware of this padding)
   stay vertically aligned with the title rather than floating off-centre
   in a taller bar. It also carries jquery-ui's own "ui-widget-header" class,
   which is what was drawing the dark teal border around it. */
.ui-datepicker .ui-datepicker-header {
    background: var(--main-color);
    border: none;
    border-radius: var(--radius-lg);
}
.ui-datepicker .ui-datepicker-title { color: #ffffff; font-weight: 600; margin: 0 38px; }
.ui-datepicker .ui-datepicker-title select { font-family: inherit; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text-primary); }

/* Month nav - styled as a segment of the bar itself rather than a button
   floating inside it: full header height, flush against the outer edge,
   rounded only on that outer corner (matching the header's own radius) so
   it reads as part of the bar, not a separate control sitting on top. */
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next {
    top: 0;
    bottom: 0;
    height: auto;
    width: 34px;
    border: none;
    cursor: pointer;
    color: rgba(255,255,255,0.85);
    background: transparent;
    transition: background var(--transition), color var(--transition);
}
.ui-datepicker .ui-datepicker-prev { left: 0; border-radius: var(--radius-lg) 0 0 var(--radius-lg); }
.ui-datepicker .ui-datepicker-next { right: 0; border-radius: 0 var(--radius-lg) var(--radius-lg) 0; }
.ui-datepicker .ui-datepicker-prev span,
.ui-datepicker .ui-datepicker-next span { display: none; }
.ui-datepicker .ui-datepicker-prev:before,
.ui-datepicker .ui-datepicker-next:before {
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    font-size: 12px;
    color: inherit;
    position: absolute;
    left: 50%; top: 50%;
    transform: translate(-50%, -50%);
}
.ui-datepicker .ui-datepicker-prev:before { content: "\f053"; }
.ui-datepicker .ui-datepicker-next:before { content: "\f054"; }
.ui-datepicker .ui-datepicker-prev:hover,
.ui-datepicker .ui-datepicker-next:hover {
    background: rgba(255,255,255,0.15);
    color: #ffffff;
}
/* jquery-ui's own hover classes nudge the button 1px via top/left/right -
   an old "pressed button" effect that reads as an unwanted jump here. Pin
   them back to the exact same position as the non-hover state. */
.ui-datepicker .ui-datepicker-prev-hover { top: 0; left: 0; }
.ui-datepicker .ui-datepicker-next-hover { top: 0; right: 0; }
.ui-datepicker .ui-datepicker-prev.ui-state-disabled,
.ui-datepicker .ui-datepicker-next.ui-state-disabled { opacity: 0.35; cursor: default; }

/* The calendar grid is a real <table>, so it inherits the generic data-table
   zebra-striping/row-hover rules from the TABLES section below - only
   override the colours those add, not sizing/spacing. It also inherits the
   generic row's backdrop-filter blur, which on top of the popup's own glass
   blur doubles up and muddies the background - turn it off for this table. */
.ui-datepicker tr {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}
.ui-datepicker tr:nth-child(even),
.ui-datepicker tr:nth-child(odd),
.ui-datepicker tr:hover,
.ui-datepicker tr.evenRow,
.ui-datepicker tr.oddRow { background: none; }
.ui-datepicker th { background: none; color: var(--text-muted); text-transform: none; letter-spacing: normal; border: none; }
.ui-datepicker td { border: none; }
/* jquery-ui's default theme puts a border on every ui-state-default/-hover/
   -active day link - kill it everywhere, on every state, per request. */
.ui-datepicker td a,
.ui-datepicker td span {
    text-align: center;
    border: none !important;
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    transition: background var(--transition), color var(--transition);
}
.ui-datepicker td a:hover { background: var(--brand-light-green); color: var(--main-color); border: none !important; }
.ui-datepicker td .ui-state-active { background: var(--main-color) !important; color: #ffffff !important; border: none !important; }
/* Today's ring removed for now - day-cell styling is getting a proper pass later */
.ui-datepicker .ui-datepicker-today a { box-shadow: none; }
.ui-datepicker .ui-datepicker-buttonpane { border-top: 1px solid var(--border); }
.ui-datepicker .ui-datepicker-buttonpane button {
    font-family: inherit;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text-primary);
    cursor: pointer;
}
.ui-datepicker .ui-datepicker-buttonpane button:hover { background: var(--surface-alt); border-color: var(--main-color); color: var(--main-color); }


/* ============================================================
   CUSTOM / APP-SPECIFIC STYLES
   ============================================================ */

/* Field enabled / disabled indicator (from customStyle) */
.fieldEnabled  { background: #eaf7ee !important; color: #2a6534 !important; }
.fieldDisabled  { background: #fff0f0 !important; color: #c0392b !important; }

/* Permit display */
.permit {
    padding: 12px;
    border: 4px solid var(--main-color);
    border-radius: var(--radius);
    margin-bottom: 12px;
    background: linear-gradient(135deg, rgba(140,192,102,0.10) 0%, rgba(200,144,80,0.08) 100%), rgba(255,255,255,0.82);
    -webkit-backdrop-filter: blur(1px);
    backdrop-filter: blur(1px);
}
.permit h2, .section h2 {
    font-size: 16px;
    background: var(--main-color);
    color: #fff;
    padding: 10px 14px;
    margin-bottom: 12px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-radius: var(--radius-sm);
}
.permitOptions { display: flex; flex-flow: row wrap; gap: 10px; }
.permitOptionsSection { flex: 1 1 320px; }
.permitSectionsContainer { display: flex; flex-flow: row wrap; gap: 12px; }
.section {
    flex: 1 1 280px;
    background: linear-gradient(135deg, rgba(140,192,102,0.10) 0%, rgba(200,144,80,0.08) 100%), rgba(255,255,255,0.82);
    -webkit-backdrop-filter: blur(1px);
    backdrop-filter: blur(1px);
    border: 1px solid rgba(140,192,102,0.22);
    border-radius: var(--radius-lg);
    padding: 12px;
}
.section.permitDetails { flex: 1 1 700px; }
.section.permitDetails .formItems { display: flex; flex-flow: row wrap; gap: 10px; }
.section.permitDetails .formItems .formItem { flex: 1 1 calc(50% - 6px); min-width: 280px; }

/* Log entries */
#permitLogs { display: none; border-top: 1px solid var(--border); margin-top: 12px; }
.permitLogHeader {
    padding: 10px 14px;
    background: var(--surface-alt);
    border-bottom: 1px solid var(--border);
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-weight: 600;
    cursor: pointer;
    font-size: 13px;
    color: var(--text-primary);
    transition: background var(--transition);
}
.permitLogHeader:hover { background: var(--brand-light-green); }
.permitLogToggleIcon { margin-right: 8px; color: var(--text-muted); }
.permitLogHeaderText { display: flex; justify-content: space-between; align-items: center; flex: 1 1 auto; }
.permitLogBody { border-bottom: 1px solid var(--border); }
.permitLogData tr { background: none; }
.permitLogData th { text-align: right; background: none; color: var(--text-secondary); vertical-align: top; border-left: 0; white-space: nowrap; font-size: 12px; }
.permitLogData tr:first-child th, .permitLogData tr:first-child td { border-top: none; }
.permitLogData tr:last-child  th, .permitLogData tr:last-child  td { border-bottom: none; }
.permitLogData td { width: 100%; text-align: left; border-right: 0; }
.permitLogChange { display: flex; gap: 8px; align-items: center; }
.changed-field  { padding: 3px 0; }
.old-value { color: #c0392b; margin-right: 6px; }
.old-value del { text-decoration-color: #c0392b; }
.new-value { color: #2a6534; }

/* Editing lock */
.editingLockMessage {
    width: 100%;
    background: #fff0f0;
    border: 1px solid #e74c3c;
    border-radius: var(--radius);
    padding: 10px 14px;
    margin-bottom: 12px;
    color: #c0392b;
    text-align: center;
    font-weight: 600;
    font-size: 13px;
}

/* Cancelled permit banner (permit page) */
.permitCancelledBanner {
    width: 100%;
    background: #fff0f0;
    border: 1px solid #e74c3c;
    border-radius: var(--radius);
    padding: 10px 14px;
    margin-bottom: 12px;
    color: #c0392b;
    text-align: center;
    font-weight: 600;
    font-size: 14px;
}

/* Cancelled permit row (search results, view-group table) */
tr.cancelledRow {
    background: #fff0f0 !important;
    text-decoration: line-through;
    color: #c0392b;
}
tr.cancelledRow:hover {
    background: #ffe0e0 !important;
}

/* Group membership info (permit page) - its own left-aligned line below the action bar */
.permitGroupInfo {
    width: 100%;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 14px;
    margin-bottom: 12px;
    text-align: left;
    font-size: 14px;
}
/* .btn defaults to flex-grow:1 for even-fill button rows - not wanted here, there's only one */
.permitGroupInfo .btn {
    flex-grow: 0;
    margin-left: 10px;
}

/* Permit page action bar - direct-manipulation buttons on the left, links away to other
   information (search, group, lineage) on the right */
.permitActionsBar {
    display: flex;
    flex-flow: row wrap;
    justify-content: space-between;
    align-items: flex-start;
    gap: 8px;
    width: 100%;
    margin-bottom: 12px;
}
.permitActionsLeft,
.permitActionsRight {
    display: flex;
    flex-flow: row wrap;
    gap: 8px;
}

/* Cancelled permit form - strike through every field's value once cancelled, matching the
   cancelled banner/row treatment used elsewhere */
.permitCancelledForm input,
.permitCancelledForm textarea,
.permitCancelledForm select,
.permitCancelledForm .formItem > label {
    text-decoration: line-through;
}

/* Search/filter specific */
.settingsIcon { margin-right: 8px; }
.disabledIcon { color: var(--text-muted) !important; }
.noBorder { border: none; }
.testInputDateResult { padding: 14px 0; color: var(--text-secondary); font-size: 13px; }


/* ============================================================
   QUARANTINE PAGE
   ============================================================ */
#quarantineResults .tableContainer {
    will-change: transform;
}

#quarantineTable {
    border-collapse: separate;
    border-spacing: 0;
}

#quarantineTable td,
#quarantineTable th {
    border-top: 0;
    border-left: 0;
}
#quarantineTable thead tr:first-child th {

}
#quarantineTable td:first-child,
#quarantineTable th:first-child {

}

/* Sticky columns */
#quarantineTable th.q-sticky-left,
#quarantineTable td.q-sticky-left {
    position: sticky;
    left: 0;
    z-index: 1;
    background-color: inherit;
}
#quarantineTable th.q-sticky-right,
#quarantineTable td.q-sticky-right {
    position: sticky;
    right: 0;
    z-index: 2;
    background-color: inherit;
}
#quarantineTable th.q-sticky-right-inner,
#quarantineTable td.q-sticky-right-inner {
    position: sticky;
    right: 0;
    z-index: 1;
    background-color: inherit;
    box-shadow: -1px 0 0 var(--border);
}
#quarantineTable th.q-sticky-left, #quarantineTable th.q-sticky-right, #quarantineTable th.q-sticky-right-inner {
    background-color: #f7f8f6;
}
#quarantineTable thead th.q-sticky-left,
#quarantineTable thead th.q-sticky-right { z-index: 3; }
#quarantineTable thead th.q-sticky-right-inner { z-index: 2; }

/* Scroll fade indicators — pseudo-elements match the tableContainerWrap overflow fades exactly */
#quarantineTable th.q-sticky-left::after,
#quarantineTable td.q-sticky-left::after,
#quarantineTable th.q-sticky-right-inner::before,
#quarantineTable td.q-sticky-right-inner::before {
    content: '';
    position: absolute;
    top: 0; bottom: 0;
    width: 48px;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.2s ease;
}
#quarantineTable th.q-sticky-left::after,
#quarantineTable td.q-sticky-left::after {
    left: 100%;
    background: linear-gradient(to right, rgba(0,0,0,0.07), transparent);
}
#quarantineTable th.q-sticky-right-inner::before,
#quarantineTable td.q-sticky-right-inner::before {
    right: 100%;
    background: linear-gradient(to left, rgba(0,0,0,0.07), transparent);
}
#quarantineTable th.q-sticky-left.q-shadow-right::after,
#quarantineTable td.q-sticky-left.q-shadow-right::after,
#quarantineTable th.q-sticky-right-inner.q-shadow-left::before,
#quarantineTable td.q-sticky-right-inner.q-shadow-left::before {
    opacity: 1;
}

.q-row-actions {
    display: flex;
    gap: 4px;
    justify-content: center;
    white-space: nowrap;
}
.q-action-btn {
    padding: 4px 7px;
    line-height: 1;
}


/* ============================================================
   FLEX / LAYOUT UTILITIES
   ============================================================ */
#content .flex-container {
    display: flex;
    flex-flow: row wrap;
    width: 100%;
    gap: 12px;
    margin-bottom: 12px;
}
#content .flex-item { flex: 1 1 480px; }

.dataContainer {
    width: 100%;
    padding: 0;
    display: flex;
    flex-flow: row wrap;
    justify-content: space-between;
    gap: 10px;
}

.dataItem { width: 100%; margin: 0 auto 10px; position: relative; }
.formItem p { padding: 14px 0; }


/* ============================================================
   LOADING BAR
   Inline results loader: branded icon with dual counter-rotating arcs
   ============================================================ */
.loading_bar {
    width: 32px;
    height: 32px;
    background-image: url('../../images/dynamic_permiserv_icon.php');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    position: relative;
    margin: 80px auto 80px;
}

/* Inner arc — spins clockwise */
.loading_bar::before {
    content: '';
    position: absolute;
    inset: -16px;
    border-radius: 50%;
    border: 2.5px solid var(--border);
    border-top-color: var(--brand-green);
    animation: spin 0.85s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* Outer arc — spins counter-clockwise */
.loading_bar::after {
    content: '';
    position: absolute;
    inset: -26px;
    border-radius: 50%;
    border: 2px solid transparent;
    border-bottom-color: var(--brand-green);
    animation: spin 1.4s cubic-bezier(0.4, 0, 0.6, 1) infinite reverse;
}


/* ============================================================
   LOADING OVERLAY
   Full-screen overlay injected by showLoadingOverlay() in sharedFunctions.js
   ============================================================ */
#loadingOverlay {
    position: fixed;
    inset: 0;
    z-index: 100001;
    background: rgba(255, 255, 255, 0.65);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

#loadingOverlaySpinner {
    position: fixed;
    z-index: 100002;
    top: 50%;
    left: 50%;
    width: 40px;
    height: 40px;
    transform: translate(-50%, -50%);
    background-image: url('../../images/dynamic_permiserv_icon.php');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
}
#loadingOverlaySpinner i { display: none !important; }
#loadingOverlaySpinner::before {
    content: '';
    position: absolute;
    inset: -18px;
    border-radius: 50%;
    border: 2.5px solid var(--border);
    border-top-color: var(--brand-green);
    animation: spin 0.85s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
#loadingOverlaySpinner::after {
    content: '';
    position: absolute;
    inset: -30px;
    border-radius: 50%;
    border: 2px solid transparent;
    border-bottom-color: var(--brand-green);
    animation: spin 1.4s cubic-bezier(0.4, 0, 0.6, 1) infinite reverse;
}

#loadingOverlayText {
    position: fixed;
    z-index: 100002;
    top: calc(50% + 60px);
    left: 50%;
    transform: translateX(-50%);
    font-size: 11px;
    font-weight: 600;
    color: var(--text-secondary);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-align: center;
    white-space: nowrap;
}


/* ============================================================
   TEXT & DISPLAY UTILITIES
   ============================================================ */
.clear         { clear: both; }
.capitalize    { text-transform: capitalize; }
.centerText, .fullWidthCentered { text-align: center; }
.underline     { text-decoration: underline; }
.boldText      { font-weight: 600; }
.italicText    { font-style: italic; }
.right-link    { float: right; }
.text-muted    { color: var(--text-muted); }
.textSuccess   { color: #2a6534; }
.textDanger    { color: #c0392b; }
.text-right    { text-align: right; }

.fa-spinner { animation: spin 0.9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Debug/data-dump tree view (helpers/phpFunctions.php's print_r_tree(),
   used by pages/examples.php, uploadPermits.php, ajax/auditing.php,
   manualEntry.php, permit.php, portalSettings.php) was a complete
   styling gap on modern - a bare <pre class="preTree"> plus the
   .arrayCollapse* expand/collapse markup print_r_tree_callback() and
   toggleArrayDisplay() (js/sharedFunctions.js) generate, with zero rules
   anywhere in this file - same class of gap as editor.css/calendar.css
   before those were ported (see
   [[project_experimental_modern_css_polish]]). Ported from
   css/template.css using modern's own tokens (neutral surface/border,
   --main-color for the accent/expand-indicator) rather than the base
   theme's raw hex/`#ccc` values. */
pre {
    border: 1px solid var(--border);
    background: var(--surface-alt);
    color: var(--text-primary);
    padding: 10px;
    margin: 5px;
    border-radius: var(--radius);
    overflow-x: scroll;
    font-size: 13px;
}
.preTree { white-space: normal; }

.arrayCollapseButton {
    margin-left: 10px;
    color: var(--main-color);
    cursor: pointer;
}
.arrayCollapseIcon {
    display: inline;
    position: relative;
    top: 2px;
    padding-right: 5px;
}
.arrayCollapseContainer {
    display: none;
    border-left: 2px solid var(--main-color);
    margin-left: 15px;
    line-height: 30px;
    padding-left: 10px;
}
.arrayCollapseClosingBracket {
    margin-left: 15px;
    color: var(--text-secondary);
}

.faButton { cursor: pointer; }
.material-icons-small { font-family: 'Material Icons'; font-weight: normal; font-style: normal; font-size: 14px; line-height: 1; letter-spacing: normal; text-transform: none; display: inline-block; white-space: nowrap; -webkit-font-feature-settings: 'liga'; -webkit-font-smoothing: antialiased; }


/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1100px) {
    #sidebar { transform: translateX(calc(-1 * var(--sidebar-width))); }
    #sidebar.open { transform: translateX(0); }
    #main-wrap { margin-left: 0; overflow-x: hidden; }
    #sidebar-toggle { align-items: center; justify-content: center; }
    #content { padding: 16px; }
    .sidebarCollapseBtn, .sidebarFooterBtn { display: none; }
    #app.sidebar-collapsed #main-wrap { margin-left: 0; }
    /* On mobile the hidden state maps to the regular off-canvas pattern */
    #app.sidebar-hidden #sidebar   { transform: translateX(calc(-1 * var(--sidebar-width))); }
    #app.sidebar-hidden #main-wrap { margin-left: 0; }
}

@media (max-width: 640px) {
    #status_badge { display: none; }
    #page-title   { display: none; }
    #user_button #user_name_display { display: none; }
    #user_button .user_chevron      { display: none; }
    .topbar-brand-text { display: none; }
    .topbar-divider    { display: none; }
}


/* ============================================================
   PRELOAD (suppress transition flash on page load)
   ============================================================ */
body.preload * { transition: none !important; }


/* ============================================================
   LOGIN PAGE
   ============================================================ */

body.bodyLogin {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #c2c2c2; /* shows through dot-grid holes in canvas */
    position: relative;
    overflow: hidden;
    padding: 24px 16px;
    box-sizing: border-box;
}

/* Canvas layers from loginTop.php handle the background — ::after not used */
body.bodyLogin::after { display: none; }

/* ---- Wrapper & card ---- */

.loginWrapper {
    position: relative;
    z-index: 10;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    max-width: 460px;
}

.login {
    width: 100%;
    background: rgba(255, 255, 255, 0.22);
    -webkit-backdrop-filter: blur(1px);
    backdrop-filter: blur(1px);
    border: 1px solid rgba(240, 240, 240, 0.45);
    border-radius: var(--radius-xl);
    box-shadow: 0 4px 28px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.06);
    overflow: hidden;
    margin: 0;
}

/* Card heading */
.login h1 {
    text-align: center;
    color: var(--text-primary);
    font-size: 17px;
    font-weight: 700;
    padding: 18px 24px 16px;
    border-bottom: 1px solid var(--border);
    text-transform: none;
    letter-spacing: -0.01em;
    background: rgba(247,248,246,0.85);
    position: relative;
    margin-bottom: 0;
    width: auto;
}

.login h1::before {
    content: '';
    position: absolute;
    bottom: -1px; left: 50%;
    transform: translateX(-50%);
    width: 36px; height: 2px;
    background: var(--main-color);
    border-radius: 2px;
    display: block;
}

/* Logo / portal title */
.loginLogo {
    display: block;
    max-width: 160px;
    height: auto;
    margin: 20px auto 4px;
    padding: 0;
    width: auto;
}

.loginTitle {
    text-align: center;
    font-size: 18px;
    font-weight: 700;
    color: var(--main-color);
    padding: 20px 24px 4px;
    letter-spacing: -0.01em;
}

/* Form area */
.login fieldset {
    padding: 16px 24px 0;
    border: none;
    margin-bottom: 0;
}

.login form { padding-bottom: 20px; }

.login p {
    padding: 8px 24px;
    font-size: 13px;
    color: var(--text-secondary);
    text-align: center;
    width: 100%;
    box-sizing: border-box;
    clear: both;
}

/* Error / success messages */
.loginError {
    display: block;
    width: 100%;
    padding: 8px 12px;
    margin: 8px 0 0;
    border-radius: var(--radius);
    background: #fff5f5;
    color: #c0392b;
    border: 1px solid #f5b7b1;
    font-size: 12px;
    text-align: left;
    box-sizing: border-box;
}

.loginSuccess {
    display: block;
    width: 100%;
    padding: 8px 12px;
    margin: 8px 0 0;
    border-radius: var(--radius);
    background: #f3faf5;
    color: #2a6534;
    border: 1px solid #b7dfbf;
    font-size: 12px;
    text-align: left;
    box-sizing: border-box;
}

/* Captcha */
.captchaContainer {
    width: 100%;
    display: flex;
    justify-content: center;
    padding: 12px 24px 0;
    box-sizing: border-box;
}

.g-recaptcha { display: inline-block; }

/* Submit button */
.login .submitButton {
    margin: 16px 24px 0;
    width: calc(100% - 48px);
    border-radius: var(--radius) !important;
}

/* "Lost your password?" link */
.loginLink {
    display: block;
    text-align: center;
    color: var(--text-muted);
    font-size: 12px;
    margin-top: 10px;
    padding: 0 24px;
    text-decoration: none;
}
.loginLink:hover { color: var(--main-color); text-decoration: underline; }

/* Google / social login */
.quickLoginButtons {
    width: 100%;
    margin-top: 10px;
}

.googleLoginButton {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 20px;
    border-radius: var(--radius);
    background: rgba(255,255,255,0.82);
    border: 1.5px solid rgba(255,255,255,0.95);
    color: var(--text-primary);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    box-shadow: 0 2px 8px rgba(0,0,0,0.10), inset 0 1px 0 rgba(255,255,255,0.9);
    transition: background var(--transition), border-color var(--transition), box-shadow var(--transition);
    width: 100%;
    box-sizing: border-box;
}
.googleLoginButton:hover {
    background: rgba(255,255,255,0.95);
    border-color: var(--main-color);
    color: var(--main-color);
    box-shadow: 0 3px 12px rgba(0,0,0,0.14), inset 0 1px 0 rgba(255,255,255,1);
}

/* Mobile */
@media (max-width: 480px) {
    .loginWrapper { padding: 0; }
    .login { border-radius: var(--radius-lg); }
    .login h1 { padding: 14px 16px 12px; font-size: 16px; }
    .login fieldset { padding: 12px 16px 0; }
    .login .submitButton { margin: 12px 16px 0; width: calc(100% - 32px); }
    .captchaContainer { padding: 10px 16px 0; }
    .loginLink { padding: 0 16px; }
}

/* ============================================================
   JQUERY UI ACCORDION
   Dashboard portlets (.accordian, examples.php) and settings-page
   accordions (customSettingsTabs.php expiry/field lists) both use the
   real jQuery UI accordion widget - reskinned here to match the modern
   palette. Ported from css/jqueryUiOverides.css (the base template's
   equivalent), swapping --alt-radius for --radius.
   ============================================================ */
/* Directional - matches which corners the widget actually flags as rounded
   (ui-corner-top: header, ui-corner-bottom: content panel below an open
   header) so an open header and its panel form one continuous rounded box
   instead of both being rounded on all 4 corners and looking disconnected
   where they meet.
   A collapsed header carries BOTH ui-corner-top (its permanent widget class,
   see jquery-ui.js's accordion `classes` map: "ui-accordion-header":
   "ui-corner-top") AND ui-corner-all (added on top via the
   "ui-accordion-header-collapsed" state map) at the same time - jQuery UI
   layers state classes rather than swapping one corner class for another.
   With single-class selectors of equal specificity, whichever rule comes
   later in the stylesheet wins regardless of which is semantically
   "correct" for that state, so ui-corner-top's top-only radius was beating
   ui-corner-all's full radius on every collapsed header. The compound
   selector below has higher specificity than either single-class rule, so
   it deterministically wins whenever both classes are present together
   (i.e. only while collapsed) and keeps the open-header/top-only case
   untouched. */
.ui-corner-all  { border-radius: var(--radius); }
.ui-corner-top  { border-radius: var(--radius) var(--radius) 0 0; }
.ui-corner-bottom { border-radius: 0 0 var(--radius) var(--radius); }
.ui-corner-right, .ui-corner-tr { border-radius: 0 var(--radius) var(--radius) 0; }
.ui-corner-all.ui-corner-top,
.ui-corner-all.ui-corner-bottom { border-radius: var(--radius); }

.ui-accordion .ui-accordion-header {
    display: flex;
    flex-flow: row;
    align-items: center;
    gap: 8px;
    padding: 10px 14px !important;
    margin-bottom: 2px !important;
    font: inherit !important;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    color: var(--text-primary);
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition), color var(--transition);
}
.ui-accordion .ui-accordion-header i { flex: 0 0 auto; }

/* Expand/collapse chevron - this build's accordion widget already swaps in
   a real FontAwesome icon here (fa-chevron-circle-right / -circle-down, see
   the icons option patched into js/jquery-ui-1.12.1.custom/jquery-ui.js),
   it just needed proper flex centering: jquery-ui.css's base .ui-icon rule
   carries a `margin-top: -.25em` meant for inline/baseline layouts, which
   throws off centering once the header is a flex row. */
.ui-accordion .ui-accordion-header-icon {
    flex: 0 0 auto;
    margin-top: 4px;
}

.ui-accordion .ui-accordion-header:not(.ui-state-active):hover {
    background: var(--brand-light-green);
    border-color: var(--main-color);
}

.ui-accordion .ui-accordion-header.ui-state-active {
    background: var(--main-color);
    border-color: var(--main-color);
    color: #ffffff;
    margin-bottom: 0 !important;
}
.ui-accordion .ui-accordion-header.ui-state-active a,
.ui-accordion .ui-accordion-header.ui-state-active a:link,
.ui-accordion .ui-accordion-header.ui-state-active a:visited { color: #ffffff; }

/* Header action buttons/links (delete/link buttons in the header bar) -
   a bare <button> has no styling of its own anywhere else in modern, so it
   was rendering with the browser's default chrome. Push it to the far
   right of the flex header and give it a compact icon-button treatment. */
.ui-accordion-header > span:last-child,
.ui-accordion-header > a.right-link,
.ui-accordion-header > .accordianHeaderButton {
    margin-left: auto;
}
.ui-accordion-header button,
.accordianHeaderButton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px; height: 26px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    font: inherit;
    cursor: pointer;
    transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.ui-accordion-header button:hover,
.accordianHeaderButton:hover {
    background: rgba(0,0,0,0.06);
    border-color: var(--border);
    color: var(--main-color);
}
.ui-accordion-header.ui-state-active button,
.ui-accordion-header.ui-state-active .accordianHeaderButton { color: rgba(255,255,255,0.85); }
.ui-accordion-header.ui-state-active button:hover,
.ui-accordion-header.ui-state-active .accordianHeaderButton:hover {
    background: rgba(255,255,255,0.15);
    border-color: transparent;
    color: #ffffff;
}

.ui-accordion .ui-accordion-content {
    background: var(--surface);
    border: 1px solid var(--border);
    border-top: none;
    padding: 14px;
}

/* Hide the jquery-ui triangle sprite for any other (non-accordion) use of
   this project's custom "ui-icon-custom" class-injection pattern. */
.ui-icon-custom {
    text-indent: 0;
    width: auto;
    background-image: unset !important;
    padding-right: 10px;
}

/* Disabled / warning / error accordion headers (customSettingsTabs.php expiry + field lists) */
.ui-disabled.ui-accordion-header { background: var(--surface-alt) !important; border-color: var(--border-strong) !important; color: var(--text-muted) !important; }
.ui-disabled.ui-accordion-header a { color: var(--text-muted) !important; }
.ui-state-active.ui-disabled.ui-accordion-header { background: var(--text-muted) !important; border-color: var(--text-muted) !important; color: #ffffff !important; }

.ui-warning.ui-accordion-header { background: var(--brand-orange-bg) !important; border-color: #fac36a !important; color: #7a3c00 !important; }
.ui-warning.ui-accordion-header a { color: #7a3c00 !important; }
.ui-state-active.ui-warning.ui-accordion-header { background: var(--brand-orange) !important; border-color: var(--brand-orange) !important; color: #ffffff !important; }

.ui-error.ui-accordion-header { background: #fff0f0 !important; border-color: #f5b7b1 !important; color: #c0392b !important; }
.ui-error.ui-accordion-header a { color: #c0392b !important; }
.ui-state-active.ui-error.ui-accordion-header { background: #c0392b !important; border-color: #c0392b !important; color: #ffffff !important; }

.ui-state-active.ui-disabled a, .ui-state-active.ui-disabled a:link, .ui-state-active.ui-disabled a:visited,
.ui-state-active.ui-error a, .ui-state-active.ui-error a:link, .ui-state-active.ui-error a:visited,
.ui-state-active.ui-warning a, .ui-state-active.ui-warning a:link, .ui-state-active.ui-warning a:visited { color: #ffffff !important; }

@media only screen and (max-width: 600px) {
    .ui-accordion .ui-accordion-content { padding: 8px; }
}

/* ============================================================
   HTML EDITOR (custom rich-text widget, js/jqueryCustomWidgets/editor.js)
   editor.css carries both the widget's structural/functional CSS (the
   code/html view toggle, content reset) and its default look - the
   structural part must be included on every template, so it's pulled
   in directly here (same as css/style.php does for the base template)
   and then reskinned to match modern's surface/border tokens.
   ============================================================ */
.custom-editor-code-view {
    resize: none !important;
    border: 1px solid var(--main-color) !important;
    width: 100% !important;
    height: 500px !important;
    display: none;
    margin-top: 0px !important;
    padding: 10px !important;
    border-top-right-radius: 0px  !important;
    border-top-left-radius: 0px  !important;
}

.custom-editor-html-view {
    border: 1px solid var(--main-color);
    width: 100%;
    height: 500px;
    padding: 10px;
    overflow-y: scroll;
    border-bottom-right-radius: var(--alt-radius);
    border-bottom-left-radius: var(--alt-radius);
}
/* RESET CONTENT */
#content .custom-editor-html-view :is(html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video) {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
	background: none;
}
/* HTML5 display-role reset for older browsers */
#content .custom-editor-html-view :is(article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section) {
	display: block;
}
#content .custom-editor-html-view :is(body) {
	line-height: 1;
}
#content .custom-editor-html-view :is(blockquote, q) {
	quotes: none;
}
#content .custom-editor-html-view :is(blockquote:before, blockquote:after, q:before, q:after) {
	content: '';
	content: none;
}
#content, .custom-editor-html-view :is(table) {
	border-collapse: collapse;
	border-spacing: 0;
}
/* UNRESET BROWSER DEFAULTS */
#content .custom-editor-html-view :is(html) {
	box-sizing: content-box;
}

#content .custom-editor-html-view :is(body) {
	margin: 8px;
	line-height: normal;
}

#content .custom-editor-html-view :is(p) {
	margin: 1em 0;
}

#content .custom-editor-html-view :is(blockquote, figure) {
	margin: 1em 40px;
}

#content .custom-editor-html-view :is(q) {
	quotes: "“" "”" "‘" "’";

	&:before {
		content: open-quote;
	}

	&:after {
		content: close-quote;
	}
}

#content .custom-editor-html-view :is(hr) {
	border: 1px inset;
	box-sizing: border-box;
	margin: 0.5em auto;
}

#content .custom-editor-html-view :is(h1) {
	font-size: 2em;
	font-weight: bold;
	margin: 0.67em 0;
}

#content .custom-editor-html-view :is(h2) {
	font-size: 1.5em;
	font-weight: bold;
	margin: 0.83em 0;
}

#content .custom-editor-html-view :is(h3) {
	font-size: 1.17em;
	font-weight: bold;
	margin: 1em 0;
}

#content .custom-editor-html-view :is(h4) {
	font-size: 1.00em;
	font-weight: bold;
	margin: 1.33em 0;
}

#content .custom-editor-html-view :is(h5) {
	font-size: 0.83em;
	font-weight: bold;
	margin: 1.67em 0;
}

#content .custom-editor-html-view :is(h6) {
	font-size: 0.67em;
	font-weight: bold;
	margin: 2.33em 0;
}

#content .custom-editor-html-view :is(article, aside, nav, section) {

	h1 {
		font-size: 1.5em;
		font-weight: bold;
		margin: 0.83em 0;
	}

	article, aside, nav, section {

		h1 {
			font-size: 1.17em;
			font-weight: bold;
			margin: 1em 0;
		}

		article, aside, nav, section {

			h1 {
				font-size: 1.00em;
				font-weight: bold;
				margin: 1.33em 0;
			}

			article, aside, nav, section {

				h1 {
					font-size: 0.83em;
					font-weight: bold;
					margin: 1.67em 0;
				}

				article, aside, nav, section {

					h1 {
						font-size: 0.67em;
						font-weight: bold;
						margin: 2.33em 0;
					}
				}
			}
		}
	}
}

#content .custom-editor-html-view :is(table) {
	border-collapse: separate;
	border-spacing: 2px;
	border-color: gray;
}

#content .custom-editor-html-view :is(thead, tbody, tfoot, tr) {
	border-color: inherit;
	vertical-align: middle;
}

#content .custom-editor-html-view :is(td, th) {
	padding: 1px;
	vertical-align: inherit;
}

#content .custom-editor-html-view :is(th) {
	font-weight: bold
}

#content .custom-editor-html-view :is(caption) {
	text-align: center;
}

#content .custom-editor-html-view :is(ul, menu) {
	list-style-type: disc;
	margin: 1em 0;
	padding: 0 0 0 40px;
}

#content .custom-editor-html-view :is(ol) {
	list-style-type: decimal;
	margin: 1em 0;
	padding: 0 0 0 40px;
}

#content .custom-editor-html-view :is(ul, ol) {

	ul {
		list-style-type: circle;
	}

	ul, ol {

		ul {
			list-style-type: square;
		}
	}
}

#content .custom-editor-html-view :is(dd) {
	margin: 0 0 0 40px;
}

#content .custom-editor-html-view :is(dl) {
	margin: 1em 0;
}

#content .custom-editor-html-view :is(ul, ol, menu, dl) {

	ul, ol, menu, dl {
		margin: 0;
	}
}

#content .custom-editor-html-view :is(legend) {
	padding: 0 2px;
}

#content .custom-editor-html-view :is(fieldset) {
	border-style: groove;
	border-width: 2px;
	border: 2px groove ThreeDFace;
	margin: 0 2px;
	padding: 0 2px 3px;
	-webkit-padding-before: 0.35em;
	-webkit-padding-start: 0.75em;
	-webkit-padding-end: 0.75em;
	-webkit-padding-after: 0.625em;
}

#content .custom-editor-html-view :is(ins) {
	background-color: transparent;
	font-weight: inherit;
	text-decoration: underline;
}

#content .custom-editor-html-view :is(b, strong) {
	font-weight: bold;
}

#content .custom-editor-html-view :is(i, cite, em, var, address, dfn) {
	font-style: italic;
	font-weight: inherit;
}

#content .custom-editor-html-view :is(abbr[title], dfn[title]) {
	border-bottom: 0;
	cursor: default;
	font-weight: inherit;
}

#content .custom-editor-html-view :is(tt, code, kbd, samp) {
	font-family: monospace;
	font-weight: inherit;
}

#content .custom-editor-html-view :is(pre) {
	font-family: monospace;
	margin: 1em 0;
	white-space: pre;
}

#content .custom-editor-html-view :is(mark) {
	background-color: yellow;
	color: black;
	font-style: normal;
	font-weight: inherit;
}

#content .custom-editor-html-view :is(big) {
	font-size: larger;
	font-weight: inherit;
}

#content .custom-editor-html-view :is(small) {
	font-size: smaller;
	font-weight: inherit;
}

#content .custom-editor-html-view :is(sub, sup) {
	font-weight: inherit;
	line-height: inherit;
	position: static;
}

#content .custom-editor-html-view :is(sub) {
	font-size: smaller;
	bottom: 0;
	vertical-align: sub;
}

#content .custom-editor-html-view :is(sup) {
	font-size: smaller;
	top: 0;
	vertical-align: super;
}

#content .custom-editor-html-view :is(ruby) {

	> rt {
		font-size: 50%;
	}
}

#content .custom-editor-html-view :is(iframe) {
	border: 2px inset;
}

.custom-editor-action-bar {
    background: var(--main-color);
    width: 100%;
    padding: 10px 0px;
    border-top-right-radius: var(--alt-radius);
    border-top-left-radius: var(--alt-radius);
}

.custom-editor-action-bar .btn-group {
    padding: 0px 10px;
    float: left;
}

.custom-editor-action-bar .btn {
    margin-right: 10px;
}

/*
.custom-editor-action-bar .btn-group:first-of-type {
    margin-left: 10px;
}
*/

.custom-editor-action-bar .btn-group .btn:last-of-type {
    margin-right: 0px;
}

#code-view-text {
    color: #ffffff;
    float: left;
    padding: 10px;
}

.custom-editor-code-view.mini, .custom-editor-html-view.mini  {
    height: 200px !important;
}

.custom-editor-action-bar.mini {
    padding: 5px 0px;
}

.custom-editor-action-bar.mini .btn-group {
    padding: 0px 5px;
}
/*
.custom-editor-action-bar.mini .btn-group:first-of-type {
    margin-left: 5px;
}
*/
.custom-editor-action-bar.mini .btn, .custom-editor-action-bar.mini #code-view-text {
    font-size: 12px;
    padding: 5px;
    margin-right: 5px;
}


.custom-editor-action-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-bottom: none;
    border-radius: var(--radius) var(--radius) 0 0;
    padding: 6px 8px !important;
}
.custom-editor-action-bar .clear { display: none; }
.custom-editor-action-bar .btn-group {
    display: flex;
    align-items: center;
    gap: 2px;
    float: none !important;
    padding: 0 6px !important;
    border-right: 1px solid var(--border);
}
.custom-editor-action-bar .btn-group:last-of-type { border-right: none; }
.custom-editor-action-bar div[style*="float: right"] {
    margin-left: auto;
    float: none !important;
    border-right: none;
    padding-right: 0 !important;
}
.custom-editor-action-bar .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px; height: 30px;
    padding: 0 !important;
    margin-right: 0 !important;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    font-size: 13px;
    box-shadow: none;
}
.custom-editor-action-bar .btn:hover {
    background: var(--surface);
    border-color: var(--border);
    color: var(--main-color);
}
.custom-editor-action-bar .btn-disabled,
.custom-editor-action-bar .btn-disabled:hover {
    background: transparent;
    border-color: transparent;
    color: var(--text-muted);
    opacity: 0.4;
    cursor: default;
}
.custom-editor-action-bar.mini { padding: 4px 6px !important; gap: 3px; }
.custom-editor-action-bar.mini .btn-group { padding: 0 5px !important; gap: 1px; }
.custom-editor-action-bar.mini .btn {
    width: 24px; height: 24px;
    font-size: 11px;
    margin-right: 0 !important;
    padding: 0 !important;
}
#code-view-text { color: var(--text-secondary); font-size: 12px; padding: 0 10px; }
.custom-editor-code-view,
.custom-editor-html-view {
    border-color: var(--border) !important;
    border-radius: 0 0 var(--radius) var(--radius) !important;
}
/* The rendered HTML preview pane is arbitrary user content (an
   email/document-style preview, editor.css's own RESET CONTENT block
   treats it like one) - it should read as a page, not inherit whatever
   translucent glass surface sits behind it in modern, so a plain literal
   white (not a --surface token, which carries transparency here) rather
   than the app's usual glass background. */
.custom-editor-html-view {
    background: #fff;
}
