/* =============================================================================
 * site.modern.css — design overlay for the TwinWorX portal
 *
 * Load AFTER site.css:
 *   <link rel="stylesheet" href="~/styles/themes.v2.css" />
 *   <link rel="stylesheet" href="~/styles/site.css" />
 *   <link rel="stylesheet" href="~/styles/site.modern.css" />   <- this file
 *
 * Non-destructive: overrides only the selectors used by _Dashboard.cshtml,
 * HeaderLayout.cshtml and _Sidebar-Menu.cshtml. Remove this file and the
 * portal reverts to the old look. No cshtml markup changes required.
 *
 * Requires the tokens from themes.v2.css (surface-*, text-*, border-*,
 * state-active-*, state-hover-*, brand-*, font-*, radius-*).
 * ============================================================================= */

/* ---------------------------------------------------------------------------
 * 0. Base
 * ------------------------------------------------------------------------- */
/* body.dark-theme selectors in other stylesheets (realtime-component-dark.css
   sets #303030) outrank a bare `body` rule — match their specificity */
body,
body.dark-theme,
body.light-theme {
    font-family: var(--font-body);
    background: radial-gradient(1100px 500px at 85% -10%, var(--brand-soft), transparent 60%), var(--surface-page) !important;
    background: var(--surface-page) !important;
    color: var(--text-primary);
    font-size: 13px;
    -webkit-font-smoothing: antialiased;
}

::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background: var(--border-strong);
    border-radius: 4px;
}

    ::-webkit-scrollbar-thumb:hover {
        background: var(--state-hover-fg);
    }

/* the dashboard is a fixed-viewport app shell: the document itself never
   scrolls (inner regions manage their own overflow). The DOM nests
   .body-main inside <main>, so match by descendant, and make the wrapper
   chain height-tight. Non-shell pages keep normal scrolling. */
html {
    height: 100%;
    margin: 0 !important;
    padding: 0 !important;
}

/*body:has(.body-main) {
    height: 100%;
    margin: 0 !important;
    padding: 0 !important;*/ /* full-bleed: no inset around the app shell on any side */
/*overflow: hidden;
}

    body:has(.body-main) main {
        display: block;
        height: 100%;
        margin: 0 !important;
        padding: 0 !important;
        border: 0 !important;
        overflow: hidden;
    }*/

.body-main {
    height: 100%;
    margin: 0 !important;
    border: 0 !important;
}
/* fill main, never exceed the viewport */

/* one page background: the body gradient. Intermediate wrappers must not
   paint their own (old css / panel css gives some of them solid darks). */
.body-main,
.content-dashboard,
.main-content-dashboard,
.left-sidebar-dashboard,
.rightPanel {
    background-color: transparent;
}

/* layout/section row wrappers (rows carry data-section across pages) */
[data-section] {
    background-color: transparent;
}

/* SAME background on every page (match the dashboard): the per-page
   content-area wrappers stay transparent so the single page floor shows
   through. Panels, sidebars, and the 3D canvas keep their own surfaces.
   !important beats the legacy fills (e.g. .main-content-reports paints the
   card tone, which made the Trending content area lighter than the rest). */
.body-main > .content,
.main-content-reports,
.main-content-assets,
.main-content-area-reports {
    background-color: transparent !important;
}

/* the dashboard tab strip: compact segmented control (like the target's
   Energy/Water switcher), not full-width blocks */
.menuBar {
    height: 44px;
    display: flex;
    align-items: center;
    padding: 0 12px;
    /* background-color: transparent !important;*/
    background-color: color-mix(in srgb, var(--surface-page) 85%, transparent) !important;
    backdrop-filter: blur(8px) !important;
    border: none;
    border-bottom: 1px solid var(--border-default);
}

    .menuBar ul {
        width: fit-content; /* group hugs its tabs */
        height: auto;
        display: flex;
        align-items: center;
        gap: 3px;
        margin: 0;
        padding: 3px;
        background: var(--surface-card) !important;
        border: 1px solid var(--border-default);
        border-radius: 9px;
        overflow: visible;
    }

    .menuBar li {
        flex: 0 0 auto !important; /* tabs size to their text */
        width: auto !important;
        background-color: transparent !important;
        border: none !important;
    }

        .menuBar li a {
            display: block;
            background-color: transparent;
            border: none !important;
            color: var(--text-secondary);
            font-weight: 500;
            font-size: 11.5px;
            padding: 6px 18px;
            border-radius: 6px;
            text-align: center;
            text-decoration: none;
            white-space: nowrap;
        }

            .menuBar li a:hover {
                background-color: var(--state-hover-bg);
                color: var(--state-hover-fg);
            }

            .menuBar li a.active,
            .menuBar li.active a {
                background-color: var(--state-active-bg);
                color: var(--state-active-fg);
            }

/* Kendo wrappers that paint their own panels */
.k-tabstrip,
.k-tabstrip-items-wrapper,
.k-tabstrip > .k-content,
.k-splitter,
.k-pane {
    background-color: transparent !important;
    border-color: var(--border-default) !important;
}

/* ---------------------------------------------------------------------------
 * 1. Header bar
 * ------------------------------------------------------------------------- */
.header {
    height: 46px;
    background-color: color-mix(in srgb, var(--surface-page) 85%, transparent);
    backdrop-filter: blur(8px);
    color: var(--text-primary);
    border: none;
    border-bottom: 1px solid var(--border-default);
}

    .header .logo {
        color: var(--text-primary);
        font-family: var(--font-display);
        font-weight: 600;
        font-size: 14px;
        display: flex;
        align-items: center;
        gap: 8px;
        padding-left: 14px;
    }

        /* product/site name: bold display face, like the target's "TwinWorX / Explore" */
        .header .logo > div > span:first-of-type {
            font-family: var(--font-display);
            font-weight: 700;
            font-size: 14px;
            letter-spacing: .2px;
            color: var(--text-primary);
        }

        /* the "/ Explore" edition tag: same size, lighter weight + muted colour,
           giving the demo's two-tone "TwinWorX / Explore" wordmark */
        .header .logo .twx-edition {
            font-weight: 400;
            color: var(--text-secondary);
            letter-spacing: 0;
        }

        .header .logo img {
            width: 26px;
            height: 26px;
            border-radius: 8px;
            background: var(--state-active-bg); /* brand chip, like the target's "M" mark */
            border: 1px solid var(--border-default);
            padding: 3px;
            margin: 0 6px 0 0 !important; /* neutralize inline negative margin hack */
        }

        .header .logo #spnBuildingName {
            color: var(--text-primary); /* building name reads as the title */
            font-family: var(--font-body);
            font-weight: 600;
            font-size: 12.5px;
            padding-left: 14px;
            border-left: 1px solid var(--border-default);
            margin-left: 10px;
            line-height: 1.25;
        }

            /* optional subtitle line under the building name — renders when the markup
   adds  <small>BSD City · Tangerang, Indonesia</small>  inside the name span */
            .header .logo #spnBuildingName small {
                display: block;
                color: var(--text-secondary);
                font-weight: 400;
                font-size: 10.5px;
                letter-spacing: .1px;
            }

.search input[type=text] {
    background: var(--surface-card);
    color: var(--text-primary);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-control);
}

.search button {
    background: var(--surface-card);
    color: var(--text-secondary);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-control);
}

    .search button:hover {
        color: var(--state-hover-fg);
        border-color: var(--state-hover-fg);
    }

/* header geometry: left half flexes, the new controls block pins right.
   (.left/.right were hard 50% widths in site.css) */
.header .left {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    display: flex;
    align-items: center;
}

.header .right {
    flex: 0 0 auto;
    width: auto;
}

.header-controls {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 10px;
    padding-right: 12px;
    flex: 0 0 auto;
}

    .header-controls .clock {
        font-family: var(--font-mono);
        font-size: 12px;
        color: var(--text-secondary);
    }

.icon-btn {
    width: 30px;
    height: 30px;
    border-radius: var(--radius-control);
    border: 1px solid var(--border-default);
    background: var(--surface-card);
    color: var(--text-secondary);
    display: grid;
    place-items: center;
    cursor: pointer;
    font-size: 13px;
    padding: 0;
}

    .icon-btn:hover {
        color: var(--state-hover-fg);
        border-color: var(--state-hover-fg);
    }

/* the notification partial positions itself absolutely; give it its own
   anchor so it sits in line between clock and theme toggle */
.bell-slot {
    position: relative;
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
}

    .bell-slot > * {
        position: static !important; /* re-anchor the bell trigger itself      */
        right: auto !important;
        top: auto !important;
        margin: 0 !important;
        float: none !important;
    }

/* notification bell: give the trigger the same boxed .icon-btn frame as the
   theme toggle (size + border were not matching), and turn the count badge
   into the demo's small red dot instead of a "0" circle. */
.header-controls .notification-icon {
    position: relative;
    box-sizing: border-box;
    width: 30px;
    height: 30px;
    border-radius: var(--radius-control, 8px);
    border: 1px solid var(--border-default);
    background: var(--surface-card);
    display: grid;
    place-items: center;
    cursor: pointer;
    padding: 0;
}

    .header-controls .notification-icon:hover {
        border-color: var(--state-hover-fg, var(--brand-2));
    }

    .header-controls .notification-icon .svg-icon {
        width: 15px;
        height: 15px;
        display: block;
    }

    /* count badge -> subtle red dot (number hidden); !important to beat notification.css */
    .header-controls .notification-icon .badge,
    .header-controls #notification-count {
        position: absolute;
        top: 5px;
        right: 6px;
        width: 6px !important;
        height: 6px !important;
        min-width: 0 !important;
        padding: 0 !important;
        border-radius: 50% !important;
        background: #FF5C6C !important;
        box-shadow: 0 0 0 3px rgba(255, 92, 108, .2);
        color: transparent !important;
        font-size: 0 !important;
        line-height: 0;
        overflow: hidden;
    }

/* ---------------------------------------------------------------------------
 * 2. Left icon rail (.leftMenu + _Sidebar-Menu.cshtml)
 * ------------------------------------------------------------------------- */
.leftMenu {
    width: 46px;
    background-color: transparent !important;
    border: none;
    border-right: 1px solid var(--border-default);
    padding-top: 6px;
}

    .leftMenu div {
        width: 34px;
        margin: 2px auto;
        padding: 8px 0;
        border-radius: 9px;
        position: relative;
        transition: background .12s, color .12s;
    }

        /* hover = brand secondary (scoped — unlike the global .active in site.css) */
        .leftMenu div:hover {
            background-color: var(--state-hover-bg);
        }

        /* active = brand primary tint + indicator bar */
        .leftMenu div.active,
        .leftMenu .first.active {
            background-color: var(--state-active-bg);
        }

            .leftMenu div.active::before {
                content: '';
                position: absolute;
                left: -6px;
                top: 7px;
                bottom: 7px;
                width: 3px;
                border-radius: 0 3px 3px 0;
                background: var(--state-active-fg);
            }

    .leftMenu img {
        width: 20px;
    }

    /* RAIL ICONS: ours are background-image <img> (not inline currentColor SVGs
       like the demo), so neither `color` nor `filter` recolors them cleanly.
       Render each themed SVG as a MASK instead: the icon SHAPE comes from the
       same --theme-*-menu url, the COLOR comes from background-color, which we
       swap on hover/active. Mirrors the demo's currentColor behavior, exactly. */
    .leftMenu div img {
        background-image: none !important; /* drop the baked-in colored image */
        background-color: var(--text-secondary); /* rest color */
        transition: background-color .12s ease;
    }

    .leftMenu div:hover img {
        background-color: var(--state-hover-fg); /* brand-2 on hover */
    }

    .leftMenu .active img {
        background-color: var(--state-active-fg); /* brand on active */
    }

    /* per-icon mask source (mask shorthand, because the --theme-*-menu vars
       carry `no-repeat`, which the mask-image longhand would reject) */
    .leftMenu img.sidebar-portfolio-menu {
        -webkit-mask: var(--theme-portfolio-menu) center / contain;
        mask: var(--theme-portfolio-menu) center / contain;
    }

    .leftMenu img.sidebar-file-menu {
        -webkit-mask: var(--theme-file-menu) center / contain;
        mask: var(--theme-file-menu) center / contain;
    }

    .leftMenu img.sidebar-home-menu {
        -webkit-mask: var(--theme-home-menu) center / contain;
        mask: var(--theme-home-menu) center / contain;
    }

    .leftMenu img.sidebar-dashboards-menu {
        -webkit-mask: var(--theme-dashboards-menu) center / contain;
        mask: var(--theme-dashboards-menu) center / contain;
    }

    .leftMenu img.sidebar-building-menu {
        -webkit-mask: var(--theme-building-menu) center / contain;
        mask: var(--theme-building-menu) center / contain;
    }

    .leftMenu img.sidebar-assets-menu {
        -webkit-mask: var(--theme-aseets-menu) center / contain;
        mask: var(--theme-aseets-menu) center / contain;
    }

    .leftMenu img.sidebar-spaces-menu {
        -webkit-mask: var(--theme-spaces-menu) center / contain;
        mask: var(--theme-spaces-menu) center / contain;
    }

    .leftMenu img.sidebar-trending-menu {
        -webkit-mask: var(--theme-trending-menu) center / contain;
        mask: var(--theme-trending-menu) center / contain;
    }

    .leftMenu img.sidebar-energy-menu {
        -webkit-mask: var(--theme-energy-menu) center / contain;
        mask: var(--theme-energy-menu) center / contain;
    }

    .leftMenu img.sidebar-alarming-menu {
        -webkit-mask: var(--theme-alarming-menu) center / contain;
        mask: var(--theme-alarming-menu) center / contain;
    }

    .leftMenu img.sidebar-scheduling-menu {
        -webkit-mask: var(--theme-scheduling-menu) center / contain;
        mask: var(--theme-scheduling-menu) center / contain;
    }

    .leftMenu img.sidebar-reports-menu {
        -webkit-mask: var(--theme-reports-menu) center / contain;
        mask: var(--theme-reports-menu) center / contain;
    }

    .leftMenu img.sidebar-customreports-menu {
        -webkit-mask: var(--theme-customreports-menu) center / contain;
        mask: var(--theme-customreports-menu) center / contain;
    }

    .leftMenu img.sidebar-reportrepository-menu {
        -webkit-mask: var(--theme-reportrepository-menu) center / contain;
        mask: var(--theme-reportrepository-menu) center / contain;
    }

    .leftMenu img.sidebar-occupants-menu {
        -webkit-mask: var(--theme-occupants-menu) center / contain;
        mask: var(--theme-occupants-menu) center / contain;
    }

    .leftMenu img.sidebar-DocumentaionRepository-menu {
        -webkit-mask: var(--theme-docrepo-menu) center / contain;
        mask: var(--theme-docrepo-menu) center / contain;
    }

/* ---------------------------------------------------------------------------
 * SHARED-COMPONENT LOCK: the header (HeaderLayout) and icon rail (_Sidebar-Menu)
 * render on every page, but some pages link their own stylesheets AFTER this
 * file and resize / re-font them, so they drift from the dashboard. Re-assert
 * the v2 numbers with !important so the shared chrome is identical everywhere.
 * ------------------------------------------------------------------------- */
.leftMenu {
    width: 46px !important;
}

    .leftMenu div {
        width: 34px !important;
        margin: 2px auto !important;
        padding: 8px 0 !important;
    }

    .leftMenu img {
        width: 20px !important;
        height: 20px !important;
    }

.header {
    height: 46px !important;
}

    .header .logo {
        font-family: var(--font-display) !important;
        font-size: 14px !important;
        font-weight: 600 !important;
    }

        .header .logo > div > span:first-of-type {
            font-family: var(--font-display) !important;
            font-weight: 700 !important;
            font-size: 14px !important;
        }

/* ---------------------------------------------------------------------------
 * 3. Page heading strip (tab styling lives in the segmented-control block above)
 * ------------------------------------------------------------------------- */
.menuBar .title-heading,
.menuBar .page-heading {
    background-color: transparent;
    color: var(--text-primary);
    font-weight: 600;
    font-size: 12.5px;
}

/* ---------------------------------------------------------------------------
 * 4. Dashboard shell — self-measuring grid: header / rail / tabs / content /
 *    footer each take natural height, content gets exactly what remains.
 *    No 100vh-minus-constant arithmetic to drift out of date.
 * ------------------------------------------------------------------------- */
.body-main {
    display: grid;
    height: 100%; /* fills the locked <main>; 100vh would
                                      overflow if any ancestor adds offset */
    overflow: hidden;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr) auto;
    grid-template-areas:
        "header header"
        "rail   tabs"
        "rail   content"
        "footer footer";
}

.header {
    grid-area: header;
}

.leftMenu {
    grid-area: rail;
    float: none;
    height: auto;
}

.menuBar {
    grid-area: tabs;
    width: auto;
}

.footer {
    grid-area: footer;
    position: static;
    width: auto;
}

.rightPanel {
    display: none;
}
/* empty legacy column */

.content-dashboard {
    grid-area: content;
    border-top: none;
    display: flex;
    gap: 10px;
    padding: 10px;
    width: auto;
    height: auto; /* the grid row supplies the height */
    min-height: 0;
    overflow: hidden;
}

/* Spaces / assets pages use a bare `.content` as the main column (the dashboard
   uses `.content-dashboard`). It isn't mapped to a grid area, so it auto-places
   into the wrong row, and spaceswithglb.css forces height:calc(100% - 35px) with
   the OLD 35px header which overshoots the 46px v2 header. Map it into the grid
   and let the row own the height. Scoped to a direct child of .body-main so the
   dashboard (which has no bare .content child) is untouched. */
.body-main > .content {
    grid-area: content;
    /*height: auto !important;*/
    min-height: 0;
    overflow: hidden;
    padding: 0 !important;
}

/* The assets layout (main-content-assets -> assets-container -> assets-content-area)
   sized to its table/canvas content, leaving the lower area empty. .content now
   fills the grid row, so cascade a height chain down so the canvas/tables take the
   full area (the 3D canvas needs it). IDs are used where present so this beats the
   later-loaded legacy assetswithtable.css. padding:0 throughout removes the body
   inset (the dashboard body has no outer padding). */
#main-content.main-content-assets {
    height: 100%;
    min-height: 0;
    padding: 0 !important;
    background: transparent;
}

    #main-content.main-content-assets .assets-container {
        height: 100%;
        min-height: 0;
        padding: 0 !important;
        border: 1px solid var(--border-strong) !important;
    }

#main-content-area-assets.assets-content-area {
    height: 100%;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: 0 !important;
}

/* title bar keeps its natural height; the visible canvas/tables fill the rest */
#main-content-area-assets > #assets-canvas,
#main-content-area-assets > #assets-tables {
    flex: 1 1 auto;
    min-height: 0;
}

/* Assets/spaces pages: a page-specific legacy stylesheet repaints the header
   solid green, beating the global .header rule. Re-assert the dark frosted v2
   header with higher specificity + !important so it matches the dashboard. */
.body-main > .header {
    background-color: color-mix(in srgb, var(--surface-page) 85%, transparent) !important;
    backdrop-filter: blur(8px) !important;
    border-bottom: 1px solid var(--border-default) !important;
}

/* Floor menu (.main-content-menu -> #ulspace): a distinct boxed nav panel --
   a raised surface-card box with a full border + rounded corners, floated with a
   small margin so it reads as a contained panel (the rail stays transparent).
   Inside: muted item text, brand-2 hover, brand-tint active row + left accent bar.
   The <a> carries an inline color, so text colours need !important; the box
   bg/border/radius need !important to beat the later-loaded page sheet. */
.main-content-menu {
    background-color: var(--surface-card) !important;
    border: 1px solid var(--border-default) !important;
    margin: 8px !important;
}

    .main-content-menu #ulspace {
        margin: 0;
        padding: 6px;
        list-style: none;
    }

        .main-content-menu #ulspace li {
            border: none;
            /*border-radius: var(--radius-control, 8px);*/
            margin: 2px 0;
            position: relative;
            transition: background-color .12s;
        }

            .main-content-menu #ulspace li a {
                display: block;
                padding: 8px 12px;
                font-family: var(--font-body);
                font-size: 12px;
                color: var(--text-secondary) !important;
                text-decoration: none;
                border: none;
            }

            .main-content-menu #ulspace li:hover {
                background-color: var(--state-hover-bg) !important;
            }

                .main-content-menu #ulspace li:hover a {
                    color: var(--state-hover-fg) !important;
                }

            .main-content-menu #ulspace li.active {
                background-color: var(--state-active-bg) !important;
            }

                .main-content-menu #ulspace li.active a {
                    color: var(--state-active-fg) !important;
                    font-weight: 500;
                }

                /* active-floor accent bar — mirrors the icon rail's .leftMenu div.active::before
           so the floor list and rail share one active treatment */
                .main-content-menu #ulspace li.active::before {
                    content: '';
                    position: absolute;
                    left: 0;
                    top: 7px;
                    bottom: 7px;
                    width: 3px;
                    border-radius: 0 3px 3px 0;
                    background: var(--state-active-fg);
                }

/* SAFETY: some pages (e.g. /layouts/*) still render these as table-cells.
   Table-cell baseline alignment pushes content to the bottom whenever a
   sibling cell (the sidebar drawer) is visible — force top alignment so
   content renders correctly whether or not the flex conversion applies. */
.left-sidebar-dashboard,
.content-divider,
.main-content-dashboard {
    vertical-align: top !important;
}

.left-sidebar-dashboard {
    display: flex; /* was table-cell */
    flex-direction: column;
    gap: 10px;
    flex: 0 0 auto;
    width: 240px; /* CSS owns this. Open/close JS no longer
                                      writes inline widths — flex handles it. */
    height: 100%;
    overflow: hidden; /* NO sidebar scrollbar */
    padding-right: 0;
}

/* divider: a 1px hairline seam between sidebar and content, with the
   collapse button floating centered on it. Same open/close JS handlers. */
.content-divider {
    display: block; /* was table-cell */
    flex: 0 0 1px;
    width: 1px;
    height: 100%;
    position: relative;
    overflow: visible;
    background-color: var(--border-default); /* the missing border */
    border: none;
}

    .content-divider button {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%); /* centered on the hairline */
        width: 16px;
        height: 64px;
        /* v2 grab-handle (same pattern as Assets/Spaces/Trending);
           free-standing on a divider, so both sides rounded.
           !important beats the button's inline styles. */
        border-radius: 8px !important;
        background-color: var(--surface-raised) !important;
        border: 1px solid var(--border-default) !important;
        box-shadow: none;
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 5;
        padding: 0;
        cursor: pointer;
    }

        .content-divider button:hover {
            /* opaque base + gradient layer: translucent tint alone is
               invisible on a 16px sliver */
            background-color: var(--surface-raised) !important;
            background-image: linear-gradient(var(--state-hover-bg), var(--state-hover-bg)) !important;
            border-color: var(--border-default) !important;
        }

    .content-divider i {
        color: var(--text-secondary) !important; /* inline color: white on the <i> */
        background: transparent !important;
        font-size: 13px;
    }

    .content-divider button:hover i {
        color: var(--text-primary) !important;
    }

/* ---------------------------------------------------------------------------
 * 5. Left info sidebar -> no-scroll column of cards:
 *    hero (compact, fixed) / building info (flexes to fill) / weather (bottom)
 * ------------------------------------------------------------------------- */
.left-sidebar-dashboard .sidebar-container {
    height: auto;
    min-height: 0;
    margin-bottom: 0;
    flex: 0 0 auto;
    background: var(--surface-card);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    overflow: hidden;
}

/* all sidebar cards size to their content (demo behavior). The column may
   end with empty space below the weather card on tall screens — that's
   the gap, not card padding bloat. */
#sidebar-two {
    flex: 0 0 auto;
}

/* hero: small photo strip + alarm chips */
#sidebar-one .ban-logo-img {
    height: 92px;
    width: calc(100% - 20px);
    margin: 0 10px;
    object-fit: cover;
    border-radius: 8px;
    border-bottom: none;
}

/* building info absorbs ALL remaining height — labels get the space */
#sidebar-two {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden; /* clip rather than scroll; type is compact */
}

/* weather card (the partial's classes restyled via the twx-weather ancestor —
   two-class selector beats weather.css's single-class rules, load order moot).
   Kept also at #sidebar-three for layouts pages that haven't been transplanted. */
#sidebar-three .weather-widget,
.twx-weather .weather-widget {
    display: block;
    height: auto;
    min-height: 0;
    padding: 0 13px 12px;
    margin: 0;
    background: transparent;
}

#sidebar-three .current-weather,
.twx-weather .current-weather {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    background: transparent;
    height: auto;
    margin: 0;
    padding: 0;
}

#sidebar-three .current-city,
.twx-weather .current-city {
    display: flex;
    flex-direction: column-reverse; /* markup: name, temp → shown: temp, name */
    text-align: left;
    gap: 1px;
    margin: 0;
    padding: 0;
}

#sidebar-three .city-temp,
.twx-weather .city-temp {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 22px;
    letter-spacing: -0.01em;
    color: var(--text-primary);
    margin: 0;
    padding: 0;
    line-height: 1.1;
}

#sidebar-three .city-name,
.twx-weather .city-name {
    font-size: 10.5px;
    color: var(--text-secondary);
    margin: 0;
    padding: 0;
}

#sidebar-three .current-forecast,
.twx-weather .current-forecast {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
    margin: 0;
    text-align: center;
}

    #sidebar-three .current-forecast img,
    .twx-weather .current-forecast img {
        width: 30px;
        height: 30px;
    }

#sidebar-three .forecast-text,
.twx-weather .forecast-text {
    font-size: 10px;
    color: var(--text-secondary);
    margin: 0;
}

/* tile titles: quiet mono eyebrows instead of solid filled strips */
.tile-title {
    background-color: transparent;
    color: var(--text-faint);
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: .14em;
    text-transform: uppercase;
    padding: 10px 0 6px 13px;
    margin-top: 0;
    height: auto;
}

    .tile-title img {
        height: 14px;
        width: 14px;
        margin-right: 8px;
        opacity: .7;
    }

    .tile-title p {
        margin: 0;
    }

.ban-logo-img {
    height: calc(100% - 88px);
    border-bottom: 1px solid var(--border-default);
    border-radius: 8px;
    width: calc(100% - 20px);
    margin: 0 10px;
}

/* alarm severity chips (legacy markup — _Dashboard kept these, layouts page
   moved to .twx-chips). Old site.css fixed the row at height:42px which was
   too short for labels — kept !important here because site.css still ships. */
.tile-alarms {
    gap: 6px;
    padding: 8px 10px 10px;
    height: auto !important;
    align-items: stretch;
}

    .tile-alarms div,
    .tile-alarms div:first-child {
        flex: 1;
        min-width: 0;
        height: auto !important;
        background: var(--surface-raised);
        border: 1px solid var(--border-default);
        border-radius: 9px;
        text-align: center;
        padding: 6px 2px;
        overflow: hidden;
    }

    .tile-alarms a {
        text-decoration: none;
        display: block;
        line-height: 1;
    }

    .tile-alarms p {
        margin: 0;
        font-family: var(--font-display);
        font-weight: 600;
        font-size: 13px;
        line-height: 1.1;
    }

    .tile-alarms .critical p {
        color: var(--status-alarm);
    }

    .tile-alarms .medium p {
        color: var(--status-warning);
    }

    .tile-alarms .low p {
        color: var(--status-info);
    }

    .tile-alarms .info p {
        color: var(--status-ok);
    }

    /* severity labels under the counts (markup carries numbers only) */
    .tile-alarms a::after {
        display: block;
        font-family: var(--font-body);
        font-size: 7.5px;
        font-weight: 500;
        letter-spacing: .04em;
        color: var(--text-faint);
        margin-top: 3px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .tile-alarms .critical a::after {
        content: 'CRITICAL';
    }

    .tile-alarms .medium a::after {
        content: 'HIGH';
    }

    .tile-alarms .low a::after {
        content: 'LOW';
    }

    .tile-alarms .info a::after {
        content: 'INFO';
    }

    /* when the markup carries its own labels (new sidebar), the CSS labels stand down */
    .tile-alarms.labeled a::after {
        content: none !important;
    }

.sev-label {
    display: block;
    font-family: var(--font-body);
    font-size: 7.5px;
    font-weight: 500;
    letter-spacing: .04em;
    color: var(--text-faint);
    margin-top: 3px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* two-column key/value rows (label left, value right) like the target */
.building-info .kv-group {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--border-default);
}

.building-info .kv {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
}

    .building-info .kv .k {
        color: var(--text-secondary);
    }

    .building-info .kv .v {
        color: var(--text-primary);
        font-weight: 500;
        text-align: right;
    }

/* building info */
.building-info {
    padding: 0 13px 10px;
}

    .building-info p {
        color: var(--text-secondary);
        font-size: 11px;
        line-height: 1.45;
        margin: 0 0 1px;
    }

    .building-info .title {
        color: var(--text-primary);
        font-weight: 600;
        font-size: 12.5px;
        margin-top: 8px;
    }

    /* bold labels ("GFA:", "NLA:") read as keys */
    .building-info b,
    .building-info strong {
        color: var(--text-primary);
        font-weight: 600;
    }

    /* the big "Office" / "Amenities" headings become small accent section tags,
   matching the target design */
    .building-info h1, .building-info h2, .building-info h3, .building-info h4,
    .sidebar-container h1, .sidebar-container h2, .sidebar-container h3, .sidebar-container h4 {
        font-family: var(--font-body);
        font-size: 11px;
        font-weight: 600;
        color: var(--series-6); /* fixed accent, not brand */
        letter-spacing: .02em;
        margin: 10px 0 3px;
        padding-top: 8px;
        border-top: 1px solid var(--border-default);
    }

    .building-info a {
        color: var(--state-active-fg);
        text-decoration: none;
    }

        .building-info a:hover {
            color: var(--state-hover-fg);
        }

/* ---------------------------------------------------------------------------
 * 6. KPI grid: flex column, four equal flexible rows, sections as cards.
 *    width:auto !important lets flex own the width even though the
 *    open/close sidebar JS writes inline widths on this element.
 * ------------------------------------------------------------------------- */
.main-content-dashboard {
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    height: 100%;
    overflow: hidden;
    border: none;
}

    .main-content-dashboard .kpi-container {
        display: grid;
        gap: 10px;
        margin: 0;
        min-height: 0;
        height: auto;
    }

        /* per-row vertical share — KPI strip slim, others taller */
        .main-content-dashboard .kpi-container:has(.kpi-consumption) {
            flex: 2 1 0;
        }

        .main-content-dashboard .kpi-container:has(.kpi-usage) {
            flex: 1 1 0;
        }

        .main-content-dashboard .kpi-container:has(.kpi-demand) {
            flex: 2 1 0;
        }

        .main-content-dashboard .kpi-container:has(.kpi-graph-2) {
            flex: 2 1 0;
        }

        /* per-row column ratios. Scoped under .main-content-dashboard for higher
   specificity than the base .kpi-container rule above. */

        /* row 1 (consumption): gauge tile fixed-width, chart(s) take what's left.
   Width chosen so the title + D/M/Y pills fit unwrapped. */
        .main-content-dashboard .kpi-container:has(.kpi-consumption) {
            grid-template-columns: 360px 1fr;
        }

        .main-content-dashboard .kpi-container:has(.kpi-consumption + .kpi-consumption + .kpi-consumption) {
            grid-template-columns: 360px 1fr 1fr;
        }

        /* row 2 (usage): equal columns regardless of count (4 or 6) */
        .main-content-dashboard .kpi-container:has(.kpi-usage) {
            grid-auto-flow: column;
            grid-auto-columns: 1fr;
            grid-template-columns: unset;
        }

        /* row 3 (demand): 3 equal */
        .main-content-dashboard .kpi-container:has(.kpi-demand) {
            grid-template-columns: repeat(3, 1fr);
        }

        /* row 4: graph-2 alone full; with graph-1, 1:3 */
        .main-content-dashboard .kpi-container:has(.kpi-graph-2) {
            grid-template-columns: 1fr;
        }

        .main-content-dashboard .kpi-container:has(.kpi-graph-1):has(.kpi-graph-2) {
            grid-template-columns: 1fr 3fr;
        }

/* fallback for browsers without :has(): flex equal distribution */
@supports not selector(:has(*)) {
    .main-content-dashboard .kpi-container {
        display: flex;
    }
}

.kpi-consumption, .kpi-demand, .kpi-usage, .kpi-graph-1, .kpi-graph-2 {
    float: none;
    min-width: 0;
    width: 100%; /* fill the grid cell — otherwise content-sized */
    height: 100%;
    justify-self: stretch; /* belt-and-braces against centered grid items */
    position: relative; /* components position against the section */
    background: var(--surface-card);
    border: 1px solid var(--border-default) !important; /* beats per-class border-left rules */
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    overflow: hidden;
}

    /* Chart components bake a design-time height into their inline #id rule
   (e.g. height:50.33%), which resolves against the now-relative section card and
   leaves the chart short with an empty band below it. That height is fixed, so the
   ResizeObserver can't fire either. Force the graph-row component box to fill its
   card so the chart sizes against the real cell height (and tracks later resizes). */
    .kpi-graph-1 > .inner-menu,
    .kpi-graph-2 > .inner-menu {
        top: 0 !important;
        left: 0 !important;
        right: 0 !important;
        bottom: 0 !important;
        width: 100% !important;
        height: 100% !important;
    }

/* ---------------------------------------------------------------------------
 * 7. Footer telemetry ribbon
 * ------------------------------------------------------------------------- */
.footer {
    background-color: color-mix(in srgb, var(--surface-page) 90%, transparent);
    border-top: 1px solid var(--border-default);
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--text-secondary);
}

.footer-info-value.occupied {
    color: var(--status-ok);
}

.footer-info-value.critical,
.footer-info.critical,
.footer-critical {
    color: var(--status-alarm);
}

/* ---------------------------------------------------------------------------
 * 8. Shared chrome: modals, dropdowns, Kendo touch-ups
 * ------------------------------------------------------------------------- */
.popup-modal-content,
.modal-content {
    background: var(--surface-card);
    color: var(--text-primary);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-card);
}

.modal-header, .modal-footer {
    border-color: var(--border-default);
}

.btn-primary {
    background: var(--state-active-fg);
    border-color: var(--state-active-fg);
}

    .btn-primary:hover {
        background: var(--state-hover-fg);
        border-color: var(--state-hover-fg);
    }

.dark-dropdown {
    background: var(--surface-card);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-control);
    box-shadow: var(--shadow-card);
    color: var(--text-primary);
}

/* fallback for browsers without color-mix() */
@supports not (color: color-mix(in oklab, red 50%, white)) {
    body {
        background: var(--surface-page);
    }

    .header, .footer {
        background-color: var(--surface-page);
    }
}

/* =============================================================================
 * 9. TWX SIDEBAR — styles for the NEW sidebar markup in _Dashboard.cshtml.
 *    Every selector here uses twx-* classes that exist in NO legacy stylesheet
 *    (site.css, weather.css, panel css), so nothing can override or be
 *    overridden by accident. Mirrors the demo design 1:1.
 * ============================================================================= */
.twx-side {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.twx-card {
    background: var(--surface-card);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    overflow: hidden;
    flex: 0 0 auto;
    display: block; /* not flex — flex was distributing extra
                                          space between eyebrow and content */
    height: auto;
    min-height: 0;
}

.twx-grow {
    flex: 1 1 auto;
}

.twx-eyebrow {
    color: var(--text-faint);
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: .14em;
    text-transform: uppercase;
    padding: 9px 13px 5px;
}

/* hero */
.twx-hero-img {
    height: 96px;
    width: calc(100% - 20px);
    margin: 0 10px;
    object-fit: cover;
    border-radius: 8px;
    display: block;
}

.twx-chips {
    display: flex;
    gap: 6px;
    padding: 8px 10px 10px;
}

.twx-chip {
    flex: 1;
    min-width: 0;
    background: var(--surface-raised);
    border: 1px solid var(--border-default);
    border-radius: 9px;
    text-align: center;
    padding: 6px 2px;
    text-decoration: none;
    overflow: hidden;
}

    .twx-chip:hover {
        border-color: var(--state-hover-fg);
    }

    .twx-chip .n {
        margin: 0;
        font-family: var(--font-display);
        font-weight: 600;
        font-size: 13px;
        line-height: 1.1;
    }

        .twx-chip .n.c-red {
            color: var(--status-alarm);
        }

        .twx-chip .n.c-amber {
            color: var(--status-warning);
        }

        .twx-chip .n.c-cyan {
            color: var(--status-info);
        }

        .twx-chip .n.c-green {
            color: var(--status-ok);
        }

    .twx-chip .l {
        display: block;
        font-size: 7.5px;
        font-weight: 500;
        letter-spacing: .04em;
        color: var(--text-faint);
        margin-top: 3px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

/* building info */
.twx-info-scroll {
    padding: 0 13px 12px;
    overflow: hidden;
    min-height: 0;
}

.twx-name {
    color: var(--text-primary);
    font-weight: 600;
    font-size: 12.5px;
    line-height: 1.3;
    margin-bottom: 4px;
}

.twx-addr {
    color: var(--text-secondary);
    font-size: 11px;
    line-height: 1.4;
}

.twx-hr {
    height: 1px;
    background: var(--border-default);
    margin: 8px 0;
}

.twx-section-tag {
    color: var(--series-6);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .02em;
    margin: 0 0 2px;
}

.twx-section-sub {
    color: var(--text-faint);
    font-weight: 400;
}

.twx-kv {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    font-size: 11px;
    line-height: 1.5;
}

    .twx-kv .k {
        color: var(--text-secondary);
    }

    .twx-kv .v {
        color: var(--text-primary);
        font-weight: 500;
        text-align: right;
    }

        .twx-kv .v a {
            color: var(--state-active-fg);
            text-decoration: none;
        }

/* weather: restyle the partial's existing classes via the new ancestor —
   (0,2,0) specificity beats weather.css's single-class rules, load order moot */
.twx-weather .weather-widget {
    padding: 0 13px 12px;
}

.twx-weather .current-weather {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    background: transparent;
    height: auto;
}

.twx-weather .current-city {
    display: flex;
    flex-direction: column-reverse; /* markup: name, temp → shown: temp, name */
    text-align: left;
    gap: 1px;
}

.twx-weather .city-temp {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 22px;
    letter-spacing: -0.01em;
    color: var(--text-primary);
    margin: 0;
    line-height: 1.1;
}

.twx-weather .city-name {
    font-size: 10.5px;
    color: var(--text-secondary);
    margin: 0;
}

.twx-weather .current-forecast {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
    text-align: center;
}

    .twx-weather .current-forecast img {
        width: 30px;
        height: 30px;
    }

.twx-weather .forecast-text {
    font-size: 10px;
    color: var(--text-secondary);
    margin: 0;
}

/* ============================================================
   Portfolio page — ALL rules scoped under .portfolio-page (added
   to the wrapper in _Portfolio.cshtml) so nothing can leak to the
   other legacy pages that share the .page-* skeleton.
   ============================================================ */
/* one .page-container child has no grid-area, so it lands in the grid's
   'auto' column and leaves the 1fr column black. Drop the grid here. */
.body-main.portfolio-page {
    display: block;
}

/* dark header bar instead of the red --theme-header-color */
.portfolio-page .page-header {
    display: flex;
    align-items: center;
    justify-content: space-between; /* logo left, controls right */
    height: 46px; /* match the dashboard .header */
    padding: 0 16px;
    background-color: color-mix(in srgb, var(--surface-page, #0B1220) 85%, transparent);
    backdrop-filter: blur(8px); /* frosted, like the dashboard header */
    color: var(--text-primary, #E7EEF8);
    border-bottom: 1px solid var(--border-default, rgba(148, 163, 184, .12));
}

    /* .left holds the logo AND an empty .search div; without flex the search stacks
   BELOW the logo and pushes it to the top of the bar. Mirror .header .left. */
    .portfolio-page .page-header .left {
        display: flex;
        align-items: center;
        flex: 1 1 auto;
        width: auto;
        min-width: 0;
    }

    /* logo: legacy .logo has padding-left:50px / width:400px; mirror the dashboard's
   .header .logo chip treatment (scoped) so it isn't indented and oversized */
    .portfolio-page .page-header .logo {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 0;
        width: auto;
        color: var(--text-primary, #E7EEF8);
        font-family: var(--font-display, 'Space Grotesk', sans-serif);
        font-weight: 600;
        font-size: 14px;
    }

        .portfolio-page .page-header .logo img {
            width: 26px;
            height: 26px;
            border-radius: 8px;
            background: var(--state-active-bg, rgba(0, 188, 212, .15));
            border: 1px solid var(--border-default, rgba(148, 163, 184, .12));
            padding: 3px;
            margin: 0 6px 0 0 !important;
        }

        .portfolio-page .page-header .logo > div > span:first-of-type {
            font-family: var(--font-display, 'Space Grotesk', sans-serif);
            font-weight: 700;
            font-size: 14px;
            letter-spacing: .2px;
            color: var(--text-primary, #E7EEF8);
        }

/* let the body's dark radial-gradient show through the content shell */
.portfolio-page .page-content,
.portfolio-page .page-content-container,
.portfolio-page .main-content-container {
    background: transparent;
}

/* empty 40px side rails on this page — hide so content fills full width */
.portfolio-page .page-left-section,
.portfolio-page .page-right-section {
    display: none;
}

.portfolio-page .page-main-content {
    flex: 1 1 auto;
    width: auto;
    display: block; /* legacy table-column is invalid in the flex row */
    background: transparent;
}

/* 'PORTFOLIO' title strip */
.portfolio-page .main-content-titlebar {
    display: flex;
    align-items: center;
    height: 32px;
    padding: 0 14px;
    background: var(--surface-raised, #152138);
    color: var(--text-secondary, #9FB0C9);
    border-bottom: 1px solid var(--border-default, rgba(148, 163, 184, .12));
}

    /* the legacy 25px height kept this globe icon small; with no height cap the SVG
   balloons to fill the content. Constrain it (and the title text) explicitly. */
    .portfolio-page .main-content-titlebar img {
        width: 16px;
        height: 16px;
    }

    .portfolio-page .main-content-titlebar p {
        margin: 0 0 0 6px !important;
        font-size: 11px !important;
        letter-spacing: .08em;
        text-transform: uppercase;
    }

.portfolio-page .page-footer {
    background: var(--surface-card, #101A2D);
    border-top: 1px solid var(--border-default, rgba(148, 163, 184, .12));
}

/* icon toggle buttons (sidebar / menu-bar collapse carets): never show a
   focus box. Listed by container rather than button:has() to avoid :has()
   re-evaluation on the live SignalR/Highcharts pages. */
.assets-left-sidebar button:focus,
.assets-left-sidebar button:focus-visible,
.assets-right-sidebar button:focus,
.assets-right-sidebar button:focus-visible,
.left-menu-bar button:focus,
.left-menu-bar button:focus-visible,
.right-menu-bar button:focus,
.right-menu-bar button:focus-visible,
.content-divider button:focus,
.content-divider button:focus-visible {
    /* keep focus-ring suppression only; the border/background wipes
       were for the old transparent-chrome buttons and made the filled
       v2 grab-handles vanish while focused after a click */
    outline: none !important;
    box-shadow: none !important;
}
