/*
 * Page shell.
 *
 * This stylesheet does not build on the Minton theme. ShellConfiguration drops app.min.css for
 * shell pages and layout/shell.html does not put Minton's class names on the chrome, so nothing
 * here is fighting a second stylesheet - the frame and the components are drawn from scratch on
 * top of Bootstrap. Bootstrap, custom.css and the icon font stay: Bootstrap is the grid, the
 * modals, the dropdowns and the form controls every page's markup already uses, custom.css is the
 * application's own content styling, and the icon font is where mdi-* comes from.
 *
 * Everything is scoped under body.shell. Loading this file on a classic page changes nothing.
 *
 * THEMING. The colour scales and the font read --shell-* custom properties and fall back to the
 * values written here. An application does not edit this file to rebrand: buildBootstrap compiles
 * META-INF/scss/searchui/_shell-theme.scss with the application's Bootstrap customizations and
 * writes those properties into its bootstrap.min.css, so $primary drives the shell too. See
 * docs/page-shell.md.
 *
 * One constraint worth knowing before editing: the library ships Bootstrap 5.1.3. The --bs-btn-*,
 * --bs-card-* and --bs-dropdown-* component variables arrived in 5.2, so they would be silently
 * inert here. Every component below sets real properties; the tokens are ours.
 */

/* ── tokens ─────────────────────────────────────────────────────────── */
body.shell {
    /*
     * The brand scale is Bootstrap's primary, the colour template.html pages always had on their
     * buttons and links: #ff6900 in the library's bootstrap.min.css, and whatever an application's
     * own Bootstrap build sets. An earlier version hard-coded an orange scale here (#ea580c), so
     * every primary button changed colour on the shell. The hex values are that same #ff6900 scale,
     * for browsers without color-mix(); the block below derives the scale from --bs-primary. Values
     * compiled by buildBootstrap (--shell-brand-*) still win over both.
     */
    --brand-rgb: var(--shell-brand-rgb, var(--bs-primary-rgb, 255, 105, 0));
    --brand-50: var(--shell-brand-50, #fff6f0);
    --brand-100: var(--shell-brand-100, #ffeadb);
    --brand-200: var(--shell-brand-200, #ffd2b3);
    --brand-500: var(--shell-brand-500, #ff7b1f);
    --brand-600: var(--shell-brand-600, var(--bs-primary, #ff6900));
    --brand-700: var(--shell-brand-700, #d15600);
    --brand-800: var(--shell-brand-800, #a84500);
    --sl-50: var(--shell-sl-50, #f8fafc);
    --sl-100: var(--shell-sl-100, #f1f5f9);
    --sl-200: var(--shell-sl-200, #e2e8f0);
    --sl-300: var(--shell-sl-300, #cbd5e1);
    --sl-400: var(--shell-sl-400, #94a3b8);
    --sl-500: var(--shell-sl-500, #64748b);
    --sl-600: var(--shell-sl-600, #475569);
    --sl-700: var(--shell-sl-700, #334155);
    --sl-800: var(--shell-sl-800, #1e293b);
    --sl-900: var(--shell-sl-900, #0f172a);

    /*
     * Surfaces. The scale above says how light a grey is; these say what a grey is *for*, which is
     * the distinction the theme switch needs. `background: #fff` stood at fourteen places in this
     * file and meant "a card, the topbar, a menu" at most of them and "the label on an orange
     * button" at the rest - the same six characters, two meanings, only one of which a dark theme
     * may touch. Naming the first kind makes the second kind safe to leave alone.
     *
     * --sl-ground is the page behind everything, --sl-surface a card or the topbar, --sl-surface-2
     * a surface sitting on a surface (a table head, a hovered row, a floating menu). The dark
     * values are in theme-dark.css; these are the light ones and are what the file drew before.
     */
    --sl-ground: var(--shell-sl-ground, var(--bs-gray-100, #f8f9fa));
    --sl-surface: var(--shell-sl-surface, #fff);
    --sl-surface-2: var(--shell-sl-surface-2, #f8fafc);
    --sl-border: var(--shell-sl-border, var(--sl-200));
    --sl-border-strong: var(--shell-sl-border-strong, var(--sl-300));

    --shell-topbar-h: 56px;
    --shell-footer-h: 40px;
    --shell-sidebar-w: 232px;
    --shell-rail-w: 64px;
    /* The content gutter. One value, so the header, the cards and the footer line up. */
    --shell-pad: 24px;
    /* Corner radii. Kept modest on purpose: controls at 6px, cards and menus at 8px. */
    --shell-radius-sm: var(--shell-radius-sm-theme, 4px);
    --shell-radius: var(--shell-radius-theme, 6px);
    --shell-radius-lg: var(--shell-radius-lg-theme, 8px);

    margin: 0;
    min-height: 100%;
    /* Bootstrap's light grey (bg-light, #f8f9fa) - the ground template.html drew behind page
       content - so white cards stand out; the page header sits on a white band above it (see
       "page header band"). */
    background: var(--bs-gray-100, #f8f9fa);
    color: var(--sl-800);
    font-family: var(--shell-font-family, Inter, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
    font-size: 13px;
    -webkit-font-smoothing: antialiased;
}

@supports (color: color-mix(in srgb, red 50%, white)) {
    body.shell {
        --brand-50: var(--shell-brand-50, color-mix(in srgb, var(--bs-primary, #ff6900) 6%, #fff));
        --brand-100: var(--shell-brand-100, color-mix(in srgb, var(--bs-primary, #ff6900) 14%, #fff));
        --brand-200: var(--shell-brand-200, color-mix(in srgb, var(--bs-primary, #ff6900) 30%, #fff));
        --brand-500: var(--shell-brand-500, color-mix(in srgb, var(--bs-primary, #ff6900) 88%, #fff));
        --brand-700: var(--shell-brand-700, color-mix(in srgb, var(--bs-primary, #ff6900) 82%, #000));
        --brand-800: var(--shell-brand-800, color-mix(in srgb, var(--bs-primary, #ff6900) 66%, #000));
    }
}

body.shell *,
body.shell *::before,
body.shell *::after {
    box-sizing: border-box;
}

body.shell ::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}

body.shell ::-webkit-scrollbar-track {
    background: var(--sl-50);
}

body.shell ::-webkit-scrollbar-thumb {
    background: var(--sl-300);
    border-radius: 3px;
}

/* No link colour of the shell's own. Bootstrap's `a` rule already gives links the application's
   link colour (#ff6900 in the library), exactly as on template.html. A shell rule on body.shell a
   outranked Bootstrap's component colours: links drawn as badges (roles and licences on the user
   page) or buttons (System alerts) got orange text on an orange or red ground. */

/*
 * A page that declares no title must not leave a gap where the header would have been.
 *
 * :empty cannot decide this: the shell renders the heading, the title, the subtitle and the action
 * bar whether or not the page filled any of them, and Thymeleaf leaves whitespace text nodes in
 * each, which :empty counts as content. shell.js sets the attribute instead.
 */
[data-shell-empty] {
    display: none !important;
}

/* A page header that holds only the visually hidden fallback h1: out of sight, still in the document. */
body.shell .shell-page-header[data-shell-heading-only] {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* A zone is a bare insertion point a page declares for products to contribute into. It has no box
   of its own; whatever lands in it brings its own. */
body.shell .shell-zone {
    display: contents;
}

/* ── frame ──────────────────────────────────────────────────────────── */
/*
 * The document scrolls, not a pane inside it. The topbar and the sidebar stay put by being sticky.
 *
 * An earlier version fixed the frame to 100vh and scrolled .shell-content. That looks the same, but
 * pages written for template.html listen to the window's scroll, read window.scrollY, use
 * position: sticky against the viewport and animate html/body to scroll - with an inner scroller
 * all of that silently does nothing, which is how the search page stopped working under
 * replace-template.
 */
body.shell .shell-wrapper {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

body.shell .shell-body {
    display: flex;
    flex: 1;
    position: relative;
}

body.shell .shell-topbar {
    position: sticky;
    top: 0;
    height: var(--shell-topbar-h);
    padding: 0 12px;
    background: var(--sl-surface);
    border-bottom: 1px solid var(--sl-200);
    flex-shrink: 0;
    z-index: 1030;
    /* Minton's .navbar-custom, when a product head links app.min.css anyway - see "a product head
       that still links Minton" below. */
    left: auto;
    right: auto;
    box-shadow: none;
}

body.shell .shell-topbar-inner {
    display: flex;
    align-items: center;
    gap: 10px;
    height: var(--shell-topbar-h);
}

body.shell .shell-topbar-search {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 420px;
    margin: 0 auto 0 16px;
}

body.shell .shell-topbar-actions,
body.shell .shell-topbar-user {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}

body.shell .shell-topbar-user {
    margin-left: auto;
}

body.shell .shell-topbar-start {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    flex: 0 1 auto;
}

body.shell .shell-menu-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 0;
    background: transparent;
    color: var(--sl-600);
    border-radius: var(--shell-radius);
    padding: 6px 8px;
    font-size: 20px;
    line-height: 1;
    flex: 0 0 auto;
}

body.shell .shell-menu-toggle:hover {
    background: var(--sl-100);
    color: var(--sl-800);
}

/* ── brand ──────────────────────────────────────────────────────────── */
body.shell .shell-topbar-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding-left: 2px;
}

/* The dot joins the two brands without extending the sidebar's vertical edge through the topbar. */
body.shell .shell-brand-separator {
    width: 4px;
    height: 4px;
    flex: 0 0 4px;
    border-radius: 50%;
    background: var(--sl-400);
}

body.shell .shell-brand-icon {
    object-fit: contain;
    object-position: left center;
    width: auto;
    height: 30px;
    max-width: 160px;
    flex-shrink: 0;
}

body.shell .shell-brand-text {
    display: flex;
    flex-direction: column;
    justify-content: center;
    line-height: 1.2;
    min-width: 0;
}

/* The product name beside the app icon, drawn the way template.html drew it (.applus-header-text):
   large, bold and in the brand orange. It still truncates rather than pushing the topbar actions out.
   A product can change it with --shell-brand-title-color / -size / -weight on body.shell in its own
   stylesheet; nothing here defines them, so the product's value wins whichever stylesheet loads first. */
body.shell .shell-brand-title {
    font-size: var(--shell-brand-title-size, 1.5rem);
    font-weight: var(--shell-brand-title-weight, 700);
    color: var(--shell-brand-title-color, var(--brand-600, #ff6900));
    letter-spacing: -.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 360px;
}
@media (max-width: 767.98px) {
    body.shell .shell-brand-title {
        font-size: min(var(--shell-brand-title-size, 1.5rem), 1.1rem);
        max-width: 50vw;
    }
}

body.shell .shell-brand-sub {
    font-size: 9px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--brand-600);
}

/* ── sidebar ────────────────────────────────────────────────────────── */
body.shell .shell-sidebar {
    position: sticky;
    top: var(--shell-topbar-h);
    align-self: flex-start;
    height: calc(100vh - var(--shell-topbar-h));
    width: var(--shell-sidebar-w);
    background: var(--sl-surface);
    border-right: 1px solid var(--sl-200);
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    transition: width .2s ease, transform .2s ease;
    z-index: 1020;
    /* Minton's .left-side-menu is padding: 90px 0 20px with a drop shadow; see "a product head that
       still links Minton" below. */
    padding: 0;
    box-shadow: none;
}

/* The corporate logo lives in the topbar on desktop. The same identity is available in the mobile drawer. */
body.shell .shell-sidebar-header {
    display: none;
}

body.shell .shell-mobile-drawer-brand {
    min-width: 0;
}

body.shell .shell-sidebar-scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 12px 10px;
}

body.shell .shell-sidebar-footer {
    min-height: var(--shell-footer-h);
    padding: 5px 14px;
    border-top: 1px solid var(--sl-100);
    background: rgba(248, 250, 252, .7);
    display: flex;
    align-items: center;
}

body.shell .shell-sidebar-version {
    padding: 0;
    font-size: 9px;
    color: var(--sl-400);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

body.shell .shell-nav-section + .shell-nav-section {
    margin-top: 16px;
}

body.shell .shell-nav-label {
    padding: 0 8px;
    margin: 0 0 6px;
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--sl-400);
}

body.shell .shell-nav-item,
body.shell .shell-nav-sub,
body.shell .shell-nav-subsub {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    border: 0;
    background: transparent;
    text-align: left;
    text-decoration: none;
    transition: background .12s, color .12s;
}

body.shell .shell-nav-item {
    border-radius: var(--shell-radius);
    padding: 7px 10px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--sl-600);
}

/* Every level has the same text colour, hover and active state; only size and padding step down.
   The third and fourth levels used to fade to --sl-400 and lose the active background, which read
   as disabled entries rather than as deeper ones. */
body.shell .shell-nav-sub {
    border-radius: var(--shell-radius-sm);
    padding: 6px 8px;
    font-size: 12px;
    font-weight: 500;
    color: var(--sl-600);
}

body.shell .shell-nav-subsub {
    border-radius: var(--shell-radius-sm);
    padding: 5px 7px;
    font-size: 11px;
    font-weight: 500;
    color: var(--sl-600);
}

body.shell .shell-nav-item:hover,
body.shell .shell-nav-sub:hover,
body.shell .shell-nav-subsub:hover {
    background: var(--sl-50);
    color: var(--sl-800);
}

body.shell .shell-nav-item.active,
body.shell .shell-nav-sub.active,
body.shell .shell-nav-subsub.active {
    background: var(--brand-50);
    color: var(--brand-600);
    font-weight: 600;
}

body.shell .shell-nav-item:focus-visible,
body.shell .shell-nav-sub:focus-visible,
body.shell .shell-nav-subsub:focus-visible {
    outline: 2px solid rgba(var(--brand-rgb), .35);
    outline-offset: 1px;
}

body.shell .shell-nav-item-label {
    display: flex;
    align-items: center;
    gap: 9px;
    min-width: 0;
}

body.shell .shell-nav-item-label i {
    font-size: 15px;
    flex-shrink: 0;
    width: 18px;
    text-align: center;
}

body.shell .shell-nav-sub .shell-nav-item-label i,
body.shell .shell-nav-subsub .shell-nav-item-label i {
    font-size: 13px;
    width: 16px;
}

body.shell .shell-nav-item-label .sb-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* On a group whose row is a link, the chevron is its own button so the label can navigate. It has
   to look like the plain chevron next to it, and it must not inherit the row's link styling. */
body.shell .shell-nav-chevron-button {
    border: 0;
    background: transparent;
    padding: 2px;
    margin: -2px;
    line-height: 1;
    color: inherit;
    display: inline-flex;
    align-items: center;
    border-radius: var(--shell-radius-sm);
}

body.shell .shell-nav-chevron-button:hover {
    background: var(--sl-200);
}

body.shell .shell-nav-chevron-button:focus-visible {
    outline: 2px solid rgba(var(--brand-rgb), .35);
    outline-offset: 1px;
}

body.shell .shell-page-badge {
    margin-left: 8px;
    background: var(--brand-100);
    color: var(--brand-800);
    vertical-align: middle;
}

body.shell .shell-page-title > i {
    margin-right: 8px;
    color: var(--brand-600);
}

body.shell .shell-nav-chevron {
    font-size: 14px;
    color: var(--sl-400);
    transition: transform .2s;
}

body.shell .shell-nav-chevron.open {
    transform: rotate(90deg);
}

body.shell .shell-nav-group {
    overflow: hidden;
    max-height: 0;
    transition: max-height .22s ease;
}

body.shell .shell-nav-group.open {
    max-height: 1200px;
}

body.shell .shell-nav-group-inner {
    padding: 3px 0 3px 28px;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

body.shell .shell-nav-group-inner-deep {
    padding: 2px 0 2px 18px;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

/* ── indentation without icons ────────────────────────────────────────
   layout/navigation marks a group of siblings shell-nav-group--no-icons when none of them has an
   icon (a section, or a group's children). Such a group reserves no icon slot, and its rows sit one
   indent step past the text of the row they belong to, instead of an empty icon's width further.
   A group where at least one sibling has an icon keeps the slot, so its labels still line up.

   The lengths below are the rows' own: a container's rows have --shell-nav-row-pad of left padding
   and --shell-nav-slot for the icon and its gap. .shell-nav-group sits between a parent row's
   container and its children, so it reads both from the parent's container and hands the parent's
   text start down as --shell-nav-parent-text. */
body.shell {
    --shell-nav-indent-step: 14px;
}

body.shell .shell-nav-section {
    --shell-nav-row-pad: 10px;
    --shell-nav-slot: 27px;
}

body.shell .shell-nav-group-inner {
    --shell-nav-row-pad: 8px;
    --shell-nav-slot: 25px;
}

body.shell .shell-nav-group-inner-deep {
    --shell-nav-row-pad: 7px;
    --shell-nav-slot: 25px;
}

body.shell .shell-nav-group--no-icons {
    --shell-nav-slot: 0px;
}

body.shell .shell-nav-group {
    --shell-nav-parent-text: calc(var(--shell-nav-row-pad, 10px) + var(--shell-nav-slot, 27px));
}

body.shell .shell-nav-group--no-icons > :is(.shell-nav-item, .shell-nav-sub, .shell-nav-subsub) > .shell-nav-item-label {
    gap: 0;
}

/* Kept in the markup at no width, so a rail row without an icon keeps its height. */
body.shell .shell-nav-group--no-icons > :is(.shell-nav-item, .shell-nav-sub, .shell-nav-subsub) > .shell-nav-item-label > i {
    width: 0;
    overflow: hidden;
}

/* Children without icons: one step past the parent's text, whether or not the parent has an icon. */
body.shell .shell-nav-group > .shell-nav-group--no-icons {
    padding-left: calc(var(--shell-nav-parent-text) + var(--shell-nav-indent-step) - var(--shell-nav-row-pad));
}

/* Children with icons under a parent without one: the child's icon starts where the parent's text does. */
body.shell .shell-nav-group--no-icons > .shell-nav-group > :is(.shell-nav-group-inner, .shell-nav-group-inner-deep):not(.shell-nav-group--no-icons) {
    padding-left: calc(var(--shell-nav-parent-text) - var(--shell-nav-row-pad));
}

/* collapsed rail: icons only */
body.shell.shell-sidebar-collapsed .shell-sidebar {
    width: var(--shell-rail-w);
}

body.shell.shell-sidebar-collapsed .shell-sidebar .sb-text,
body.shell.shell-sidebar-collapsed .shell-sidebar .shell-nav-label,
body.shell.shell-sidebar-collapsed .shell-sidebar .shell-nav-group,
body.shell.shell-sidebar-collapsed .shell-sidebar .shell-nav-item-right {
    display: none !important;
}

body.shell.shell-sidebar-collapsed .shell-sidebar .shell-nav-item {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
}

body.shell .shell-sidebar-backdrop {
    display: none;
}

body.shell .shell-skip-link {
    border: 1px solid var(--sl-200);
    border-radius: var(--shell-radius);
    font-size: 12px;
    color: var(--sl-800);
}

/* ── content ────────────────────────────────────────────────────────── */
body.shell .shell-content {
    flex: 1;
    min-width: 0;
    min-height: calc(100vh - var(--shell-topbar-h));
    display: flex;
    flex-direction: column;
    /* clip, not hidden: content that pokes out sideways (Minton ribbons, wide tables) must not make
       the whole page scroll horizontally, and clip - unlike hidden - does not turn this into a
       scroll container, so position: sticky inside a page still sticks to the viewport. */
    overflow-x: clip;
}

/* The focused layout (shellFocus): no sidebar is rendered, so the content column is the only flex item
   and takes the width; this only guards against a product stylesheet giving it a sidebar offset. */
body.shell.shell-focused .shell-content {
    width: 100%;
    margin-left: 0;
}

body.shell .shell-content > .content {
    flex: 1;
}

body.shell .shell-container {
    padding: var(--shell-pad);
    max-width: none;
}

body.shell .shell-breadcrumb .breadcrumb {
    font-size: 11px;
    padding: 0;
    margin-bottom: 8px;
}

body.shell .shell-breadcrumb .breadcrumb-item a {
    color: var(--sl-500);
    text-decoration: none;
}

body.shell .shell-breadcrumb .breadcrumb-item a:hover {
    color: var(--brand-600);
}

body.shell .shell-page-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding-bottom: 12px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--sl-200);
}

body.shell .shell-page-title {
    font-size: 17px;
    font-weight: 700;
    color: var(--sl-900);
    letter-spacing: -.02em;
    margin: 0;
}

body.shell .shell-page-subtitle {
    font-size: 12px;
    color: var(--sl-500);
    margin: 3px 0 0;
}

body.shell .shell-page-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

/* The bar is --shell-footer-h tall, the same as the sidebar's help row beside it, and its content is
   centred in that height rather than pushed down by padding: padding only centred the one line whose
   height it was tuned for, and the dense layout's 4px left the text at the top of the bar. The vertical
   padding is the least room kept around content that wraps onto more lines (narrow screens), where
   the bar grows instead of clipping. A column, so the content row keeps the full width its
   justify-content-between needs. */
body.shell .shell-footer .footer,
body.shell .shell-footer > .footer {
    position: static;
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: var(--shell-footer-h);
    padding: 6px var(--shell-pad);
    font-size: 10px;
    color: var(--sl-400);
    background: var(--sl-surface);
    border-top: 1px solid var(--sl-200);
}

body.shell .shell-footer a {
    color: var(--sl-400);
    text-decoration: none;
}

body.shell .shell-footer a:hover {
    color: var(--sl-800);
}

/* ── components ─────────────────────────────────────────────────────── */
body.shell input[type="checkbox"],
body.shell input[type="radio"] {
    accent-color: var(--brand-600);
}

body.shell .form-check-input:checked,
body.shell .form-check-input[type="checkbox"]:indeterminate {
    background-color: var(--brand-600);
    border-color: var(--brand-600);
}

body.shell .form-check-input:focus {
    border-color: var(--brand-600);
    box-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25);
}

body.shell .card {
    border: 1px solid var(--sl-200);
    border-radius: var(--shell-radius-lg);
    background: var(--sl-surface);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .05);
    margin-bottom: 16px;
}

body.shell .card-body {
    padding: 16px;
}

body.shell .card-title {
    font-size: 14px;
    font-weight: 700;
    color: var(--sl-900);
}

body.shell .btn {
    font-size: 12.5px;
    padding: 6px 12px;
    border-radius: var(--shell-radius);
    font-weight: 500;
}

body.shell .btn-primary {
    color: #fff;
    background-color: var(--brand-600);
    border-color: var(--brand-600);
    box-shadow: 0 1px 2px rgba(0, 0, 0, .06);
}

body.shell .btn-primary:hover,
body.shell .btn-primary:focus {
    background-color: var(--brand-700);
    border-color: var(--brand-700);
}

body.shell .btn-primary:active,
body.shell .btn-primary.active {
    background-color: var(--brand-800);
    border-color: var(--brand-800);
}

body.shell .btn-secondary,
body.shell .btn-light {
    color: var(--sl-700);
    background-color: var(--sl-surface);
    border-color: var(--sl-200);
    box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
}

body.shell .btn-secondary:hover,
body.shell .btn-light:hover {
    color: var(--sl-800);
    background-color: var(--sl-50);
    border-color: var(--sl-200);
}

body.shell .btn-sm {
    font-size: 11.5px;
    padding: 4px 9px;
    border-radius: var(--shell-radius-sm);
}

/*
 * Outline buttons keep Bootstrap's colours - primary is the brand, secondary, danger and success
 * are the theme's - and get the shell's shape: a white ground, the same hairline shadow as the
 * other buttons, a filled hover, a darker press.
 *
 * Left to Bootstrap they looked unfinished next to the shell's own buttons. The ground was
 * transparent, so the slate page showed through. 5.1.3 draws its focus ring on :focus rather than
 * :focus-visible, so a 4px half-opaque ring stayed around every button after a mouse click. The
 * library's bootstrap.min.css turns btn-outline-primary's hover text white but leaves its pressed
 * text black, so the label flipped colour on mouse-down. And a product built on 5.3
 * (testdataanalyzer) fills a keyboard-focused button instead of ringing it, so the result depended
 * on the product's Bootstrap build.
 *
 * :where(body.shell) keeps these rules at Bootstrap's own specificity plus the one .btn in the
 * state rules, so they beat both Bootstrap versions by source order and a page's own stylesheet
 * can still restyle an outline button (modular-navigation.css does). Every state selector is kept
 * at the same weight - an :is() counts its heaviest argument, so .dropdown-toggle.show in the
 * pressed list would have outranked the keyboard focus ring below it. The task widget draws its
 * own (task.css).
 */
:where(body.shell) .btn-outline-primary {
    --shell-outline: var(--brand-600);
    --shell-outline-rgb: var(--brand-rgb);
    --shell-outline-pressed: var(--brand-700);
}

:where(body.shell) .btn-outline-secondary {
    --shell-outline: var(--bs-secondary, #746660);
    --shell-outline-rgb: var(--bs-secondary-rgb, 116, 102, 96);
    --shell-outline-pressed: var(--bs-secondary, #746660);
}

:where(body.shell) .btn-outline-danger {
    --shell-outline: var(--bs-danger, #dc3545);
    --shell-outline-rgb: var(--bs-danger-rgb, 220, 53, 69);
    --shell-outline-pressed: var(--bs-danger, #dc3545);
}

:where(body.shell) .btn-outline-success {
    --shell-outline: var(--bs-success, #198754);
    --shell-outline-rgb: var(--bs-success-rgb, 25, 135, 84);
    --shell-outline-pressed: var(--bs-success, #198754);
}

@supports (color: color-mix(in srgb, red 50%, white)) {
    :where(body.shell) :is(.btn-outline-secondary, .btn-outline-danger, .btn-outline-success) {
        --shell-outline-pressed: color-mix(in srgb, var(--shell-outline) 84%, #000);
    }
}

:where(body.shell) :is(.btn-outline-primary, .btn-outline-secondary, .btn-outline-danger, .btn-outline-success) {
    color: var(--shell-outline);
    background-color: var(--sl-surface);
    border-color: var(--shell-outline);
    box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
}

/* 5.3 fills a keyboard-focused button with its hover colours (primary with black text); 5.1 does
   not. The ring below is the focus indication on both. Before :hover, so hovering still fills. */
:where(body.shell) .btn:is(.btn-outline-primary, .btn-outline-secondary, .btn-outline-danger, .btn-outline-success):focus-visible {
    color: var(--shell-outline);
    background-color: var(--sl-surface);
    border-color: var(--shell-outline);
}

:where(body.shell) .btn:is(.btn-outline-primary, .btn-outline-secondary, .btn-outline-danger, .btn-outline-success):hover {
    color: #fff;
    background-color: var(--shell-outline);
    border-color: var(--shell-outline);
}

:where(body.shell) .btn:is(.btn-outline-primary, .btn-outline-secondary, .btn-outline-danger, .btn-outline-success):focus {
    box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
}

:where(body.shell) .btn:is(.btn-outline-primary, .btn-outline-secondary, .btn-outline-danger, .btn-outline-success):is(:active, .active, .show),
:where(body.shell) .btn-check:checked + .btn:is(.btn-outline-primary, .btn-outline-secondary, .btn-outline-danger, .btn-outline-success) {
    color: #fff;
    background-color: var(--shell-outline-pressed);
    border-color: var(--shell-outline-pressed);
    box-shadow: none;
}

/* After :active, so a keyboard press keeps its ring. */
:where(body.shell) .btn:is(.btn-outline-primary, .btn-outline-secondary, .btn-outline-danger, .btn-outline-success):focus-visible,
:where(body.shell) .btn-check:focus-visible + .btn:is(.btn-outline-primary, .btn-outline-secondary, .btn-outline-danger, .btn-outline-success) {
    outline: 0;
    box-shadow: 0 0 0 3px rgba(var(--shell-outline-rgb), .3);
}

:where(body.shell) .btn:is(.btn-outline-primary, .btn-outline-secondary, .btn-outline-danger, .btn-outline-success):is(:disabled, .disabled) {
    color: var(--shell-outline);
    background-color: var(--sl-surface);
    border-color: var(--shell-outline);
    box-shadow: none;
}

body.shell .form-control,
body.shell .form-select {
    font-size: 12.5px;
    padding: 6px 10px;
    border-color: var(--sl-200);
    border-radius: var(--shell-radius);
    color: var(--sl-800);
}

body.shell .form-select {
    padding-right: 30px;
}

body.shell .form-control:focus,
body.shell .form-select:focus {
    border-color: var(--brand-500);
    box-shadow: 0 0 0 3px rgba(var(--brand-rgb), .12);
}

body.shell .form-control::placeholder {
    color: var(--sl-400);
}

body.shell .form-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--sl-600);
    margin-bottom: 5px;
}

body.shell .nav-tabs {
    border-bottom: 1px solid var(--sl-200);
    gap: 4px;
}

body.shell .nav-tabs .nav-link {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--sl-500);
    border: 0;
    border-bottom: 2px solid transparent;
    padding: 8px 12px;
}

body.shell .nav-tabs .nav-link:hover {
    color: var(--sl-800);
}

body.shell .nav-tabs .nav-link.active {
    color: var(--brand-600);
    background: transparent;
    border-bottom-color: var(--brand-600);
}

body.shell .table {
    font-size: 12.5px;
    color: var(--sl-700);
    margin-bottom: 0;
}

body.shell .table > thead > tr > th {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--sl-500);
    background: var(--sl-50);
    border-bottom: 1px solid var(--sl-200);
    white-space: nowrap;
    padding: 10px 12px;
}

body.shell .table > tbody > tr > td {
    padding: 10px 12px;
    vertical-align: middle;
    border-color: var(--sl-100);
}

body.shell .table-hover > tbody > tr:hover > * {
    background: var(--sl-50);
}

body.shell .table-responsive,
body.shell .dataTables_wrapper {
    overflow-x: auto;
}

body.shell .badge {
    font-size: 10px;
    font-weight: 700;
    border-radius: var(--shell-radius-sm);
    padding: 3px 9px;
}

body.shell .dropdown-menu {
    font-size: 12.5px;
    border: 1px solid var(--sl-200);
    border-radius: var(--shell-radius-lg);
    padding: 6px;
    box-shadow: 0 20px 40px rgba(0, 0, 0, .12);
}

body.shell .dropdown-item {
    border-radius: var(--shell-radius);
    padding: 7px 10px;
    color: var(--sl-700);
}

body.shell .dropdown-item:hover,
body.shell .dropdown-item:focus {
    background: var(--sl-50);
    color: var(--sl-900);
}

body.shell .modal-content {
    border: 0;
    border-radius: var(--shell-radius-lg);
}

body.shell .alert {
    border-radius: var(--shell-radius-lg);
    font-size: 12.5px;
}

body.shell .text-muted {
    color: var(--sl-500) !important;
}

/* ── responsive ─────────────────────────────────────────────────────── */

/* tablet: the sidebar starts as an icon rail, and expanding it overlays the page rather than
   squeezing it - at this width there is not enough room for both. */
@media (min-width: 768px) and (max-width: 991.98px) {
    body.shell {
        --shell-pad: 18px;
    }

    body.shell .shell-sidebar {
        width: var(--shell-rail-w);
    }

    body.shell .shell-sidebar .sb-text,
    body.shell .shell-sidebar .shell-nav-label,
    body.shell .shell-sidebar .shell-nav-group,
    body.shell .shell-sidebar .shell-nav-item-right,
    body.shell .shell-sidebar-footer {
        display: none;
    }

    body.shell .shell-sidebar .shell-nav-item {
        justify-content: center;
        padding-left: 0;
        padding-right: 0;
    }

    /* Fixed to the viewport below the topbar: the document scrolls, so an absolute overlay would
       scroll away with the page. */
    body.shell.shell-sidebar-open .shell-sidebar {
        position: fixed;
        top: var(--shell-topbar-h);
        bottom: 0;
        left: 0;
        height: auto;
        width: var(--shell-sidebar-w);
        box-shadow: 0 10px 40px rgba(15, 23, 42, .18);
    }

    body.shell.shell-sidebar-open .shell-sidebar .sb-text,
    body.shell.shell-sidebar-open .shell-sidebar .shell-nav-label,
    body.shell.shell-sidebar-open .shell-sidebar .shell-nav-group,
    body.shell.shell-sidebar-open .shell-sidebar .shell-nav-item-right {
        display: revert;
    }

    /* flex, not revert: revert is the user agent's block, which drops the help row's centring. */
    body.shell.shell-sidebar-open .shell-sidebar-footer {
        display: flex;
    }

    body.shell.shell-sidebar-open .shell-sidebar .shell-nav-group:not(.open) {
        display: block;
    }

    body.shell.shell-sidebar-open .shell-sidebar .shell-nav-item {
        justify-content: space-between;
        padding-left: 10px;
        padding-right: 10px;
    }

    body.shell.shell-sidebar-open .shell-sidebar-backdrop {
        display: block;
        position: fixed;
        inset: var(--shell-topbar-h) 0 0 0;
        background: rgba(15, 23, 42, .35);
        z-index: 1010;
    }

    body.shell .shell-topbar-search {
        max-width: 260px;
    }
}

/* mobile: off-canvas drawer, and the topbar keeps only what is needed to navigate */
@media (max-width: 767.98px) {
    body.shell {
        --shell-pad: 14px;
    }

    body.shell .shell-sidebar {
        position: fixed;
        top: var(--shell-topbar-h);
        bottom: 0;
        left: 0;
        height: auto;
        width: min(82vw, var(--shell-sidebar-w));
        transform: translateX(-100%);
    }

    /* The shadow only while open: a closed drawer sits just off-screen and its shadow would show
       along the left edge of the page. */
    body.shell.shell-sidebar-open .shell-sidebar {
        transform: translateX(0);
        box-shadow: 0 10px 40px rgba(15, 23, 42, .2);
    }

    body.shell.shell-sidebar-open .shell-sidebar-backdrop {
        display: block;
        position: fixed;
        inset: var(--shell-topbar-h) 0 0 0;
        background: rgba(15, 23, 42, .4);
        z-index: 1010;
    }

    body.shell .shell-topbar-search {
        display: none;
    }

    body.shell .shell-topbar {
        padding-right: 6px;
        padding-left: 6px;
    }

    body.shell .shell-topbar-inner,
    body.shell .shell-topbar-start,
    body.shell .shell-topbar-brand {
        gap: 6px;
    }

    body.shell .shell-menu-toggle {
        width: 44px;
        height: 44px;
    }

    body.shell .shell-topbar-start,
    body.shell .shell-topbar-brand,
    body.shell .shell-brand-text {
        min-width: 0;
    }

    /* Corporate identity and organisation are in the drawer at this width. The compact product
       icon/name remains in the bar and gives way, by ellipsis, before the bell or account does. */
    body.shell .shell-brand-applus,
    body.shell .shell-brand-separator,
    body.shell .shell-brand-sub {
        display: none;
    }

    body.shell .shell-brand-icon {
        width: 28px;
        height: 28px;
        max-width: 28px;
    }

    body.shell .shell-brand-title {
        max-width: clamp(72px, 28vw, 150px);
    }

    body.shell .shell-sidebar-header {
        display: block;
        padding: 12px 14px 10px;
        border-bottom: 1px solid var(--sl-100);
    }

    body.shell .shell-mobile-drawer-brand {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: 5px;
    }

    body.shell .shell-mobile-applus {
        display: inline-flex;
        align-items: center;
        min-height: 32px;
    }

    body.shell .shell-mobile-applus img {
        width: auto;
        height: 28px;
    }

    body.shell .shell-mobile-organisation {
        max-width: 100%;
        overflow: hidden;
        color: var(--sl-600);
        font-size: 12px;
        font-weight: 600;
        line-height: 1.25;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* The phone bar deliberately keeps the two time-sensitive user controls. Apps & Services and
       organisation selection remain available after opening navigation/account respectively. */
    body.shell .shell-topbar-user > nav > .dropdown-wide {
        display: none;
    }

    body.shell .shell-topbar-user .notification-list > .dropdown-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 44px;
        min-height: 44px;
        border-radius: var(--shell-radius);
    }

    body.shell .shell-topbar-actions,
    body.shell .shell-topbar-user {
        gap: 2px;
    }

    body.shell .shell-page-header {
        flex-direction: column;
        align-items: flex-start;
        margin-bottom: 14px;
    }

    body.shell .shell-page-actions {
        width: 100%;
    }

    body.shell .shell-page-actions > .btn {
        flex: 1 1 auto;
    }

    body.shell .table-responsive,
    body.shell .dataTables_wrapper {
        -webkit-overflow-scrolling: touch;
    }

    body.shell .card {
        border-radius: var(--shell-radius-lg);
        margin-bottom: 12px;
    }
}

@media (min-width: 1600px) {
    body.shell {
        --shell-pad: 32px;
    }
}

/* Set by the boot script in layout/shell.html until shell.js has restored the sidebar and its
   open groups, so the first paint does not animate from the default state. The universal selector
   is the point: it also covers .shell-nav-group's max-height and .shell-nav-chevron's rotate, which
   arrive open from the server, and Bootstrap's .collapsing in the product navigation. */
body.shell.shell-preload *,
body.shell.shell-preload *::before,
body.shell.shell-preload *::after {
    transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
    body.shell .shell-sidebar,
    body.shell .shell-nav-group,
    body.shell .shell-nav-chevron {
        transition: none !important;
    }
}

/* The theme is Bootstrap 5.1, which has no .fw-semibold (added in 5.2), so markup using it rendered
   at regular weight. With Tahoma, which has no 600 face, this draws bold. */
body.shell .fw-semibold {
    font-weight: 600 !important;
}

/* ── print ──────────────────────────────────────────────────────────── */
@media print {
    body.shell,
    body.shell .shell-wrapper {
        height: auto !important;
        overflow: visible !important;
        display: block !important;
    }

    body.shell .shell-topbar,
    body.shell .shell-sidebar,
    body.shell .shell-footer,
    body.shell .shell-sidebar-backdrop,
    body.shell .shell-floating-actions,
    body.shell .shell-floating-actions-tab,
    body.shell .no-print {
        display: none !important;
    }

    body.shell .shell-body,
    body.shell .shell-content {
        overflow: visible !important;
        display: block !important;
    }

    body.shell .card {
        box-shadow: none;
    }
}

/* template.html's content card around custom-content - see layout/shell.html. A page that fills
   the content region instead leaves it empty, and an empty card would still draw its padding. */
body.shell .shell-legacy-content:empty {
    display: none;
}

/* ── a product head that still links Minton ───────────────────────────
   ShellConfiguration drops app.min.css from the asset bundle, but a product that ships its own
   head.html links its stylesheets by hand, and the shell inserts that head as it is. testdataanalyzer
   did, and Minton's chrome rules then reached the shell's own frame through the hook classes it
   keeps (left-side-menu, navbar-custom, button-menu-mobile): `.left-side-menu { padding: 90px 0 20px }`
   left an empty band above the navigation, and once app.min.js switched <body> to
   data-sidebar-size="condensed" (it does between 768 and 1028px) the sidebar was forced to 70px with
   !important and <body> to min-height: 1550px, so the page scrolled as well as the sidebar.
   The plain declarations (padding, shadow, the topbar's left offset, the 70px toggle button) are
   reset in the frame rules above, which outrank Minton's selectors and still give way to the
   shell's own open and mobile states. What Minton marks !important, or selects more specifically,
   is taken back here. Without Minton on the page none of this matches anything. */
body.shell[data-sidebar-size="condensed"]:not([data-layout="compact"]):not(.auth-fluid-pages) {
    min-height: 100%;
}

body.shell[data-sidebar-size="condensed"] .shell-sidebar.left-side-menu {
    width: var(--shell-sidebar-w) !important;
}

body.shell.shell-sidebar-collapsed[data-sidebar-size="condensed"] .shell-sidebar.left-side-menu {
    width: var(--shell-rail-w) !important;
}

@media (min-width: 768px) and (max-width: 991.98px) {
    body.shell[data-sidebar-size="condensed"] .shell-sidebar.left-side-menu {
        width: var(--shell-rail-w) !important;
    }

    body.shell.shell-sidebar-open[data-sidebar-size="condensed"] .shell-sidebar.left-side-menu {
        width: var(--shell-sidebar-w) !important;
    }
}

@media (max-width: 767.98px) {
    body.shell[data-sidebar-size="condensed"] .shell-sidebar.left-side-menu {
        width: min(82vw, var(--shell-sidebar-w)) !important;
    }
}

/* ── an application's own sidebar ─────────────────────────────────────
   An application that ships footer/navigation keeps that sidebar on the product menu (see
   layout/shell.html). Its markup is Minton's - a fixed left-side-menu, simplebar scaffolding and
   #side-menu-multi - and Minton's app.min.js still marks the active link and opens its group.
   This draws it like the shell's own navigation. */
body.shell .shell-product-navigation .left-side-menu {
    position: static;
    width: auto;
    height: auto;
    padding: 0;
    background: transparent;
    box-shadow: none;
}

body.shell .shell-product-navigation .logo-box,
body.shell .shell-product-navigation .simplebar-track,
body.shell .shell-product-navigation .simplebar-placeholder,
body.shell .shell-product-navigation .simplebar-height-auto-observer-wrapper {
    display: none;
}

body.shell .shell-product-navigation [data-simplebar],
body.shell .shell-product-navigation .simplebar-wrapper,
body.shell .shell-product-navigation .simplebar-mask,
body.shell .shell-product-navigation .simplebar-offset,
body.shell .shell-product-navigation .simplebar-content-wrapper {
    position: static !important;
    height: auto !important;
    margin: 0 !important;
    overflow: visible !important;
}

body.shell .shell-product-navigation ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

body.shell .shell-product-navigation .menu-title {
    padding: 0 8px;
    margin: 12px 0 6px;
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--sl-400);
}

body.shell .shell-product-navigation #side-menu-multi li > a {
    display: flex;
    align-items: center;
    gap: 9px;
    border-radius: var(--shell-radius);
    padding: 7px 10px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--sl-600);
    text-decoration: none;
    transition: background .12s, color .12s;
}

body.shell .shell-product-navigation #side-menu-multi .nav-second-level {
    padding-left: 18px;
}

body.shell .shell-product-navigation #side-menu-multi .nav-second-level li > a {
    padding: 6px 8px;
    font-size: 12px;
}

body.shell .shell-product-navigation #side-menu-multi li > a:hover {
    background: var(--sl-50);
    color: var(--sl-800);
}

body.shell .shell-product-navigation #side-menu-multi li > a.active,
body.shell .shell-product-navigation #side-menu-multi li.menuitem-active > a {
    background: var(--brand-50);
    color: var(--brand-600);
    font-weight: 600;
}

body.shell .shell-product-navigation #side-menu-multi li > a i {
    font-size: 15px;
    width: 18px;
    flex-shrink: 0;
    text-align: center;
}

body.shell .shell-product-navigation #side-menu-multi .menu-arrow {
    margin-left: auto;
    transition: transform .15s;
}

body.shell .shell-product-navigation #side-menu-multi .menu-arrow::before {
    font-family: "Material Design Icons";
    content: "\F0142";
}

body.shell .shell-product-navigation #side-menu-multi a[aria-expanded="true"] .menu-arrow {
    transform: rotate(90deg);
}

body.shell.shell-sidebar-collapsed .shell-product-navigation .menu-title,
body.shell.shell-sidebar-collapsed .shell-product-navigation #side-menu-multi li > a span,
body.shell.shell-sidebar-collapsed .shell-product-navigation #side-menu-multi .menu-arrow,
body.shell.shell-sidebar-collapsed .shell-product-navigation #side-menu-multi .nav-second-level {
    display: none;
}

/* ── topbar: user area ────────────────────────────────────────────────
   usernav renders Minton's topnav-menu list (company switcher, user menu). Without Minton's
   stylesheet its <li>s stack; lay them out on one row and drop the grid gutters inside them. */

/* The theme switch in the user menu, which user-menu.css hides. It is shown here, in the one
   stylesheet only the shell loads, because the shell is the only layout that can be themed: a
   legacy-layout page still has Minton's app.min.css and would go half-dark. This rule and the
   th:if on #shellThemeBoot in head.html are the same decision written twice - change them
   together. See the header of theme-dark.css. */
body.shell .sui-usermenu .sui-usermenu-theme {
    display: block;
}

body.shell .shell-topbar-user .topnav-menu {
    display: flex;
    align-items: center;
    gap: 8px;
    float: none !important;
    margin: 0;
}

body.shell .shell-topbar-user .topnav-menu > li {
    display: flex;
    align-items: center;
}

body.shell .shell-topbar-user .topnav-menu > li.d-none {
    display: none !important;
}

@media (min-width: 768px) {
    body.shell .shell-topbar-user .topnav-menu > li.d-md-inline-block {
        display: flex !important;
    }
}

body.shell .shell-topbar-user .topnav-menu .row {
    flex-wrap: nowrap;
    margin: 0;
}

body.shell .shell-topbar-user .topnav-menu .col {
    padding: 0;
}

body.shell .shell-topbar-user .nav-user {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 4px 8px !important;
    border-radius: var(--shell-radius);
    white-space: nowrap;
    color: var(--sl-700);
}

body.shell .shell-topbar-user .nav-user:hover {
    background: var(--sl-100);
}

body.shell .shell-topbar-user .nav-user .badge {
    display: inline-flex;
    align-items: center;
    border-radius: var(--shell-radius) !important;
    padding: 4px 8px !important;
    font-size: 12px !important;
}

/* usernav's own gap-3 is too wide for a phone next to the brand: the items would draw over it. */
@media (max-width: 575.98px) {
    body.shell .shell-topbar-user > nav {
        gap: 4px !important;
    }

    body.shell .shell-topbar-user .topnav-menu:not(:has(li)) {
        display: none;
    }
}

body.shell .shell-topbar-user .pro-user-name {
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── topbar: Applus+ mark ───────────────────────────────────────────── */
/* Leads the brand; the small neutral dot after it separates corporate and product identity. */
body.shell .shell-brand-applus {
    display: flex;
    align-items: center;
    gap: 6px;
    padding-right: 0;
    margin-right: 0;
    font-size: 11px;
    font-weight: 600;
    color: var(--sl-500);
    text-decoration: none;
    white-space: nowrap;
}

/* The Applus+ Laboratories wordmark (238x78). Height-driven so the bar stays 56px. */
body.shell .shell-brand-applus img {
    width: auto;
    height: 30px;
}

body.shell .shell-brand-applus:hover {
    color: var(--sl-800);
}

/* ── sidebar footer: help and version ─────────────────────────────── */
body.shell .shell-sidebar-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
}

body.shell .shell-sidebar-help > a {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11.5px;
    font-weight: 500;
    color: var(--sl-600);
    text-decoration: none;
    border-radius: var(--shell-radius);
    padding: 2px 5px;
}

body.shell .shell-sidebar-help > a:hover {
    background: var(--sl-100);
    color: var(--sl-900);
}

body.shell .shell-sidebar-help i {
    font-size: 15px;
}

body.shell .shell-sidebar-version {
    cursor: default;
    white-space: nowrap;
}

/* Still a centring flex row of --shell-footer-h: a block with 8px padding made the rail's help row
   4.5px taller than the page footer beside it. */
body.shell.shell-sidebar-collapsed .shell-sidebar-footer {
    display: flex;
    padding: 5px 0;
}

body.shell.shell-sidebar-collapsed .shell-sidebar-meta {
    justify-content: center;
}

body.shell.shell-sidebar-collapsed .shell-sidebar-help .sb-text,
body.shell.shell-sidebar-collapsed .shell-sidebar-version {
    display: none;
}

/* ── page header band ──────────────────────────────────────────────────
   The title, breadcrumb and a page's top-level tabs sit on one white band across the content
   column, so the header reads as its own area above the light grey content ground. The band is the
   elements' own background pulled out to the container edges with negative margins; nothing is
   wrapped, so pages need no markup change. Tabs join the band when they are the first thing in the
   content (the merged-tabs admin pages: ul.nav-tabs.admin-merged-tabs). */
body.shell .shell-breadcrumb:not([data-shell-empty]) {
    display: block;
    background: var(--sl-surface);
    margin: calc(-1 * var(--shell-pad)) calc(-1 * var(--shell-pad)) 0;
    padding: 12px var(--shell-pad) 0;
}

body.shell .shell-breadcrumb:not([data-shell-empty]) .breadcrumb {
    margin-bottom: 0;
}

body.shell .shell-page-header:not([data-shell-empty]) {
    background: var(--sl-surface);
    margin: 0 calc(-1 * var(--shell-pad)) 18px;
    padding: 16px var(--shell-pad) 14px;
}

body.shell .shell-breadcrumb[data-shell-empty] + .shell-page-header:not([data-shell-empty]) {
    margin-top: calc(-1 * var(--shell-pad));
    padding-top: 20px;
}

/* The header's rule becomes the tabs' rule when the tabs continue the band. */
body.shell .shell-page-header:not([data-shell-empty]):has(+ .shell-page-content > section > .admin-merged-tabs:first-child) {
    border-bottom: 0;
    margin-bottom: 0;
    padding-bottom: 4px;
}

body.shell .shell-page-content > section > .admin-merged-tabs:first-child {
    background: var(--sl-surface);
    margin: 0 calc(-1 * var(--shell-pad)) 18px;
    padding: 0 var(--shell-pad);
    border-bottom: 1px solid var(--sl-200);
}

body.shell .shell-page-header[data-shell-empty] + .shell-page-content > section > .admin-merged-tabs:first-child {
    margin-top: calc(-1 * var(--shell-pad));
    padding-top: 8px;
}

/* custom.css gives every .tab-content a 20px top margin; the band already separates it. */
body.shell .shell-page-content > section > .admin-merged-tabs:first-child + .tab-content {
    margin-top: 0;
}

/* ── rail flyouts ─────────────────────────────────────────────────────
   shell.js shows a label tooltip or a submenu panel beside the icon rail. The panel and the
   tooltip are appended to <body> and only ever shown while the rail is showing; the marks below
   apply only to the rail, so the expanded sidebar and the mobile drawer are untouched. */
body.shell .shell-rail-flyout {
    position: fixed;
    z-index: 1040;
    min-width: 190px;
    max-width: 320px;
    overflow-y: auto;
    padding: 4px;
    background: var(--sl-surface);
    border: 1px solid var(--sl-200);
    border-radius: var(--shell-radius-lg);
    box-shadow: 0 8px 24px rgba(15, 23, 42, .12);
    font-size: 12.5px;
    line-height: 1.3;
}

body.shell .shell-rail-flyout-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 10px 8px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--sl-100);
    color: var(--sl-900);
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

body.shell .shell-rail-flyout-header i {
    font-size: 16px;
    width: 18px;
    text-align: center;
    color: var(--brand-600);
}

body.shell a.shell-rail-flyout-header:hover {
    color: var(--brand-700);
}

body.shell .shell-rail-flyout-list {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

body.shell .shell-rail-flyout-entry {
    display: block;
    padding: 7px 10px;
    border-radius: var(--shell-radius-sm);
    color: var(--sl-600);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The same colours as the rows in the expanded sidebar, on every level. */
body.shell a.shell-rail-flyout-entry:hover {
    background: var(--sl-50);
    color: var(--sl-800);
}

body.shell .shell-rail-flyout-entry.active {
    background: var(--brand-50);
    color: var(--brand-600);
    font-weight: 600;
}

/* A deeper level renders indented inside the same panel, as the expanded sidebar nests it: the panel
   shows no icons, so by the sidebar's indent step. */
body.shell .shell-rail-flyout-deep {
    padding-left: calc(10px + var(--shell-nav-indent-step, 14px) * var(--shell-flyout-depth, 1));
    font-size: 12px;
}

body.shell span.shell-rail-flyout-parent {
    font-weight: 500;
}

body.shell .shell-rail-flyout-heading {
    padding: 8px 10px 3px;
    font-size: 11px;
    color: var(--sl-400);
}

body.shell .shell-rail-flyout a:focus-visible {
    outline: 2px solid rgba(var(--brand-rgb), .35);
    outline-offset: -2px;
}

body.shell .shell-rail-tip {
    position: fixed;
    z-index: 1040;
    transform: translateY(-50%);
    padding: 5px 9px;
    background: var(--sl-900);
    /* --sl-50, not #fff: the ground is the far end of the scale and the scale mirrors in the dark
       theme, so a literal white label here would be white on near-white as soon as the switch is
       thrown. The two tokens move together and the chip stays legible in both. */
    color: var(--sl-50);
    font-size: 12px;
    line-height: 1.3;
    border-radius: var(--shell-radius-sm);
    white-space: nowrap;
    pointer-events: none;
}

body.shell .shell-rail-tip::before {
    content: "";
    position: absolute;
    left: -4px;
    top: 50%;
    margin-top: -4px;
    border-style: solid;
    border-width: 4px 4px 4px 0;
    border-color: transparent var(--sl-900) transparent transparent;
}

@media (min-width: 992px) {
    body.shell.shell-sidebar-collapsed .shell-sidebar .shell-nav-item.active,
    body.shell.shell-sidebar-collapsed .shell-sidebar .shell-nav-item.shell-rail-has-active,
    body.shell.shell-sidebar-collapsed .shell-product-navigation #side-menu-multi > li > a.shell-rail-has-active,
    body.shell.shell-sidebar-collapsed .shell-product-navigation #side-menu-multi > li > a.active:not([href^="#"]) {
        background: var(--brand-600);
        color: #fff;
    }

    body.shell.shell-sidebar-collapsed .shell-sidebar .shell-rail-parent-icon {
        position: relative;
        display: inline-block;
    }

    body.shell.shell-sidebar-collapsed .shell-sidebar .shell-rail-parent-icon::after {
        content: "";
        position: absolute;
        right: -3px;
        bottom: 0;
        border-style: solid;
        border-width: 0 0 3px 3px;
        border-color: transparent transparent currentColor transparent;
        opacity: .6;
    }

    body.shell.shell-sidebar-collapsed .shell-product-navigation #side-menu-multi li > a > .mdi-chevron-right {
        display: none;
    }
}

@media (min-width: 768px) and (max-width: 991.98px) {
    body.shell:not(.shell-sidebar-open) .shell-sidebar .shell-nav-item.active,
    body.shell:not(.shell-sidebar-open) .shell-sidebar .shell-nav-item.shell-rail-has-active,
    body.shell:not(.shell-sidebar-open) .shell-product-navigation #side-menu-multi > li > a.shell-rail-has-active,
    body.shell:not(.shell-sidebar-open) .shell-product-navigation #side-menu-multi > li > a.active:not([href^="#"]) {
        background: var(--brand-600);
        color: #fff;
    }

    body.shell:not(.shell-sidebar-open) .shell-sidebar .shell-rail-parent-icon {
        position: relative;
        display: inline-block;
    }

    body.shell:not(.shell-sidebar-open) .shell-sidebar .shell-rail-parent-icon::after {
        content: "";
        position: absolute;
        right: -3px;
        bottom: 0;
        border-style: solid;
        border-width: 0 0 3px 3px;
        border-color: transparent transparent currentColor transparent;
        opacity: .6;
    }

    /* The tablet rail hid the shell navigation's labels but not a product navigation's. */
    body.shell:not(.shell-sidebar-open) .shell-product-navigation .menu-title,
    body.shell:not(.shell-sidebar-open) .shell-product-navigation #side-menu-multi li > a span,
    body.shell:not(.shell-sidebar-open) .shell-product-navigation #side-menu-multi li > a > .mdi-chevron-right,
    body.shell:not(.shell-sidebar-open) .shell-product-navigation #side-menu-multi .menu-arrow,
    body.shell:not(.shell-sidebar-open) .shell-product-navigation #side-menu-multi .nav-second-level {
        display: none;
    }
}

/* ── company area: the company above the page title, and the switch to another one ─────────── */
body.shell .shell-company-switch {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 2px;
    font-size: 12px;
    color: var(--sl-500);
}

body.shell .shell-company-switch-name,
body.shell .shell-company-switch-toggle {
    font-weight: 600;
    color: var(--brand-600);
}

body.shell .shell-company-switch-toggle {
    background: none;
    border: 0;
    padding: 2px 4px;
    margin-left: -4px;
    border-radius: var(--shell-radius-sm);
    font-size: 12px;
}

body.shell .shell-company-switch-toggle:hover,
body.shell .shell-company-switch-toggle:focus-visible {
    background: var(--brand-50, #fff6f0);
}

body.shell .shell-company-switch-menu {
    max-height: 60vh;
    overflow-y: auto;
    font-size: 13px;
}

/* ── the dense layout (shellDense) ───────────────────────────────────────
   For a page that is one big working surface - the search table, the datasheet - every pixel of
   gutter is a pixel of data lost. shell-dense takes the gutter down from 24/32px (14px on phones) to
   6px (4px on phones) on every side, so content runs to the edges of the content column at any
   width, and compacts what sits around the content: the header band, the gaps between cards, the
   legacy content card and the footer. The topbar, the sidebar and its rail, the drawer and print are
   untouched.

   It works through --shell-pad, the one gutter everything above is measured in - the container, the
   band's negative margins, the footer - so those stay aligned without restating them. body.shell.shell-dense
   is one class more specific than every breakpoint's body.shell, so the value holds at all widths.
   Nothing caps the width: .shell-container has no max-width, and neither does anything added here. */
body.shell.shell-dense {
    --shell-pad: 6px;
}

@media (max-width: 767.98px) {
    body.shell.shell-dense {
        --shell-pad: 4px;
    }
}

body.shell.shell-dense .shell-breadcrumb:not([data-shell-empty]) {
    padding-top: 6px;
}

body.shell.shell-dense .shell-page-header,
body.shell.shell-dense .shell-page-header:not([data-shell-empty]) {
    margin-bottom: var(--shell-pad);
    padding-top: 6px;
    padding-bottom: 6px;
}

body.shell.shell-dense .shell-breadcrumb[data-shell-empty] + .shell-page-header:not([data-shell-empty]) {
    padding-top: 6px;
}

body.shell.shell-dense .shell-page-title {
    font-size: 15px;
}

body.shell.shell-dense .shell-page-content > section > .admin-merged-tabs:first-child {
    margin-bottom: var(--shell-pad);
}

body.shell.shell-dense .card {
    margin-bottom: var(--shell-pad);
}

/* template.html's content card (p-2 bg-light, see layout/shell.html): on a dense page its 8px of padding
   is exactly the gutter this layout removes. Bootstrap's p-2 is !important. */
body.shell.shell-dense .shell-legacy-content {
    padding: 0 !important;
    background: transparent !important;
}

/* The dynamic search/datasheet editor is itself a bordered, two-pane workspace. When it is on a
   dense route, remove the last shell gutter around that workspace; other dense pages keep 6/4px. */
body.shell.shell-dense .shell-container:has(.cfg-editor-root) {
    padding: 0;
}

body.shell.shell-dense .shell-page-content:has(.cfg-editor-root) > section,
body.shell.shell-dense .company-config:has(.cfg-editor-root) {
    margin: 0;
    padding: 0;
}

body.shell.shell-dense .shell-footer .footer,
body.shell.shell-dense .shell-footer > .footer {
    padding-top: 4px;
    padding-bottom: 4px;
}

/* ── floating actions ────────────────────────────────────────────────────
   One stack in the bottom right corner (#shellFloatingActions, assets/js/shell/floating-actions.js).
   The assistant's launcher and the datasheet's buttons used to position themselves and landed on each
   other and on the last rows of the page. See "Floating actions" in docs/page-shell.md.

   - offset: the stack's distance from the corner, and the space kept between it and the content above;
   - lift: set by the script - how far the footer (or an alert banner) reaches into the viewport;
   - height: set by the script - the stack's own height, 0 while nothing in it is visible.

   z-index 1034: above the content, the sticky table headers and the topbar, below the assistant's open
   drawer (1035), the rail flyouts (1040) and Bootstrap's modals (1050). While the sidebar is open as an
   overlay the stack drops under its backdrop (1010), like the rest of the page. */
body.shell {
    --shell-floating-actions-offset: 20px;
    --shell-floating-actions-gap: 10px;
}

@media (max-width: 575.98px) {
    body.shell {
        --shell-floating-actions-offset: 12px;
        --shell-floating-actions-gap: 8px;
    }
}

body.shell .shell-floating-actions {
    position: fixed;
    right: var(--shell-floating-actions-offset);
    bottom: calc(var(--shell-floating-actions-offset) + var(--shell-floating-actions-lift, 0px));
    z-index: 1034;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--shell-floating-actions-gap);
    /* The stack's box spans its widest item; the corners beside a narrower one stay clickable. */
    pointer-events: none;
}

body.shell .shell-floating-actions > * {
    pointer-events: auto;
}

body.shell.shell-sidebar-open .shell-floating-actions,
body.shell.shell-sidebar-open .shell-floating-actions-tab {
    z-index: 1005;
}

/* ── tucking: the whole stack out past the right edge, one tab on the edge to bring it back ──
   The look was chosen from a playground: a 22px white round button with a chevron on top of the stack,
   and an 18x36 orange half circle on the edge, rounded on the left only, level with the stack's bottom.
   The tucked stack slides and fades, then turns invisible so nothing in it can be reached; the script
   also makes it inert. */
body.shell .shell-floating-actions {
    transition: transform .25s ease, opacity .2s ease, visibility 0s linear 0s;
}

body.shell .shell-floating-actions.is-tucked {
    transform: translateX(calc(100% + var(--shell-floating-actions-offset) + 8px));
    opacity: 0;
    visibility: hidden;
    transition: transform .25s ease, opacity .2s ease, visibility 0s linear .25s;
}

body.shell .shell-floating-actions.is-tucked > * {
    pointer-events: none;
}

body.shell .shell-floating-actions-tuck {
    width: 22px;
    height: 22px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--sl-200);
    border-radius: 50%;
    background: var(--sl-surface);
    color: var(--sl-500);
    font-size: 15px;
    line-height: 1;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .1);
    cursor: pointer;
}

body.shell .shell-floating-actions-tuck:hover,
body.shell .shell-floating-actions-tuck:focus-visible {
    color: var(--sl-900);
}

body.shell .shell-floating-actions-tab {
    position: fixed;
    right: 0;
    bottom: calc(var(--shell-floating-actions-offset) + var(--shell-floating-actions-lift, 0px));
    z-index: 1034;
    width: 18px;
    height: 36px;
    padding: 0 0 0 2px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 36px 0 0 36px;
    background: var(--brand-600, #ff6900);
    color: #fff;
    font-size: 15px;
    line-height: 1;
    box-shadow: -2px 2px 6px rgba(0, 0, 0, .18);
    cursor: pointer;
    transition: width .15s ease;
}

body.shell .shell-floating-actions-tab:hover,
body.shell .shell-floating-actions-tab:focus-visible {
    width: 26px;
}

body.shell .shell-floating-actions-tab:focus-visible {
    outline: 2px solid var(--sl-900);
    outline-offset: 2px;
}

body.shell .shell-floating-actions-tab[hidden],
body.shell .shell-floating-actions-tuck[hidden] {
    display: none !important;
}

/* The assistant's unread count, mirrored while its launcher is tucked away with the stack. Same red and
   white ring as the launcher's own badge (agent-panel.css), on the tab's open side. */
body.shell .shell-floating-actions-tab-badge {
    position: absolute;
    top: -6px;
    left: -8px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    box-sizing: border-box;
    border-radius: 999px;
    background: #f5325c;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--sl-surface);
}

@media (prefers-reduced-motion: reduce) {
    body.shell .shell-floating-actions,
    body.shell .shell-floating-actions.is-tucked,
    body.shell .shell-floating-actions-tab {
        transition: none;
    }
}

/* A mounted widget brought its own fixed or absolute placement; in the stack the stack places it.
   relative, not static: a badge or a close control inside it is positioned against it. !important
   because widgets set that placement inline (the datasheet's jump-to-top) or by id. */
body.shell .shell-floating-actions > .shell-floating-action {
    position: relative !important;
    top: auto !important;
    right: auto !important;
    bottom: auto !important;
    left: auto !important;
}

/* Only datasheets reserve clearance for their bottom actions. Elsewhere the stack floats above
   content without changing the page height. Embedded datasheets do not pad the enclosing page. */
body.shell.shell-has-floating-actions .shell-container:has(.shell-page-content > #datasheet, .shell-legacy-content > #datasheet) {
    padding-bottom: calc(var(--shell-pad) + var(--shell-floating-actions-offset) + var(--shell-floating-actions-height, 0px));
}
