/*
    Do not modify this file for customizations.
    Use the custom-style.css instead.
    Any styles defined there will override the styles here.
    TODO Combine style.css and icamp-style.css into a single css file.
*/

/* Darken the panel body background */
.panel-body {
    background-color: #fafafa;
}

/* Ensure form inputs remain pure white for contrast */
.panel-body .form-control {
    background-color: #ffffff;
    border-color: #cccccc;
}

/* Optional: Use your primary color #002c4e for the active input border */
.panel-body .form-control:focus {
    border-color: #002c4e;
    box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 44, 78, 0.4);
}

/* fix for ie button drop down menu */
.dropdown-menu > li{
    list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}

/* Displays the logo in the top-left corner. */
#navbar-logo {
    background-image: url("/portal/images/logo-a67d22b87cac0a7f167382dd0023d4c9.png");
    background-size: contain;
    background-repeat: no-repeat;
    width: 250px;
    height: 80px;
    min-width: 250px;
    min-height: 80px;
}

.ics-header .navbar-header {
    min-height: 80px;
}

.ics-header .navbar-brand {
    margin: 0px 0px 0px 0px;
    padding: 0px 0px 0px 0px;
    max-width: 80%;
}

.ics-header .navbar-default {
    background-color: #002c4e;
    background-image: none;
    background-repeat: no-repeat;
    border-radius: 0;
}

.ics-header .navbar-title {
    margin-top: 20px;
}

/* http://stackoverflow.com/questions/18529274/change-navbar-color-in-twitter-bootstrap-3 */

.ics-header .navbar-default .navbar-nav > li > a {
    color: white;
}

.ics-header .navbar-default .navbar-nav > li > a:hover,
.ics-header .navbar-default .navbar-nav > li > a:focus {
    color: black;
}

/* used to get the logout button to display the same */
.ics-header .navbar-default .navbar-nav > li > form  {
    margin-top: 8px;
}
.ics-header .navbar-default .navbar-nav > li > form > button {
    color: white;
}

.ics-header .navbar-default .navbar-nav > li > form > button:hover,
.ics-header .navbar-default .navbar-nav > li > form > button:focus {
    color: black;
}

/* Override panel-primary header colors to match AHS */
.panel-primary > .panel-heading {
    background-image: none;
    background-color: #f0f4f8;
    color: #1a3a5c;
    border-bottom: none;
}

.panel-info > .panel-heading {
    background-image: none;
    color: #055160;
    background-color: #f5f5f5;
    border-bottom: none;
}

.panel-default > .panel-heading {
    background-image: none;
    background-color: #f5f5f5;
    border-bottom: none;
}

#form-contents .panel-primary .panel-title {
    font-weight: bold;
}

.panel-primary,
.panel-info,
.panel-default {
    border: none;
    box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}

.required-asterisk {
    color:red;
    font-weight:bold;
    margin-right:5px;
}

/*********** twinList ***********/
.twinList {
    width: 100%;
}

/* horrible hacky fix for angular messed up default selected option bug when using promises/ajax :( */
.twinList select option:empty {
    display:none;
}

.twinList .btn {
    margin: .15em;
    width: 55px;
}

.twinList select {
    width: 100%;
    height: 190px;
}

.twinList small {
    width: 100%;
    margin-right: auto;
    margin-left: auto;
    text-align: center;
}

.twinList .pane {
    width: 44%;
    float: left;
}

.twinList .divider {
    width: 12%;
    float: left;
    text-align: center;
    margin-top: 20px;
    margin-right: auto;
    margin-left: auto;
}
/***********          ***********/

table.middle-align > tbody > tr > td {
    vertical-align: middle;
}

.parsley-errors-list{
    color: #b94a48;
}

.required-asterisk-glyph{
    color: #de2926;
}

/* .parsley-error{
	background-color: #fff;	
} */

input.parsley-error, select.parsley-error, textarea.parsley-error {
    background-color: #fff;
    border: 1px solid #eed3d7;
    color: #555;
}

input.parsley-success, select.parsley-success, textarea.parsley-success {
    background-color: #fff;
    border: 1px solid #d6e9c6;
    color: #555;
}

/* this is used to get spacing right on the form builder for html elements */
.form-html-padding{
    padding-left: 15px;
}

.request_user-asset-parent {

}

.request_user_available-assets {
}

.request_user_available-assets-panel {
    /*box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px;*/
}

.request_user-change-access-btn {
    background-color: #c7eafb;
    background-image: linear-gradient(to bottom, #c7eafb 0%, #c4e3f3 100%);
    background-repeat: repeat-x;
    border-color: #86cce8;
}
.request_user-change-access-btn:hover {
    background-color: #c4e3f3;
    color: inherit;
}

.request_user-change-access-btn-text {
    color: #28587d;
    text-shadow: none;
}

.request_user-selected-user-and-assets-container {
    position: sticky;
    top: 30px;
}

.request_user_selected-assets-container {
    margin-top: 15px;
}

.request_user-selected-assets-content {
    padding-right: 0px;
    display:none;
    pointer-events:auto;
}

.request_user-selected-assets-panel-list {
    /*box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px;*/
}

.request_user-selected-assets-buttons {
    border-top: 0;
    padding-top: 15px;
}

.available-assets-parent {
    /* max-height: 900px; Removing this max height for now. */
    padding-top: 5px;
}

.request_selected-user-container {
    /*box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px;*/
}



.request_user-selected-assets-panel-list .list-group-item.active { /* This is the Selected Entitlements header */
    background-color: #bce8f1;
    border-color: #bce8f1;
    color: black;
    text-shadow: none;
    background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
    background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
    background-repeat: repeat-x;
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
}

td.request_user-asset-select{
    width: 8%;
}

td.request_user-asset-name {
/*    width: 30%;
    font-weight:400;
    font-size: large;*/
}

td.request_user-asset-description {
    width: 62%;
}

.selected-assets:hover {
    background-image: -webkit-linear-gradient(top, #dbdbdb 0, #F5F5F5 100%);
    background-image: -o-linear-gradient(top, #dbdbdb 0, #F5F5F5 100%);
    background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#F5F5F5));
    background-image: linear-gradient(to bottom, #dbdbdb 0, #F5F5F5 100%);
    box-shadow: inset 0 3px 0 rgba(0,0,0,.075);
}
.remove-asset:hover{
    cursor: pointer;
}
.remove-asset-glyph {
    color: rgb(51, 51, 51);
    font-size: small;
}

.remove-asset-name {
    text-decoration: none;
    color: rgb(51, 51, 51);
}

/* MT2: the scroll affordance used to be a hover-triggered "Scroll to show more..."
   label positioned at a hardcoded top: 690px inside a 725px container, shown by JS
   when height() > 720 - so it only landed correctly at exactly one content height.

   Replaced by the CSS scroll-shadow technique: the two white layers are painted
   with background-attachment: local so they travel WITH the content, the two
   radial shadows with the default scroll attachment so they stay pinned to the
   box. The shadow is therefore only visible while content is actually hidden in
   that direction - self-measuring, no JS, no magic numbers.

   Height cut from 725px (almost a full laptop viewport) to 320px, about eight
   rows, in line with the multiselect's 208px option list. */
.multitext-container {
    max-height: 320px;
    overflow-y: auto;
    background:
        linear-gradient(#fff 30%, rgba(255, 255, 255, 0)) top / 100% 14px no-repeat local,
        linear-gradient(rgba(255, 255, 255, 0), #fff 70%) bottom / 100% 14px no-repeat local,
        radial-gradient(farthest-side at 50% 0, rgba(26, 58, 92, 0.16), rgba(26, 58, 92, 0)) top / 100% 6px no-repeat,
        radial-gradient(farthest-side at 50% 100%, rgba(26, 58, 92, 0.16), rgba(26, 58, 92, 0)) bottom / 100% 6px no-repeat;
}

.multitext-single {
    padding-top: 5px;
    padding-bottom: 5px;

}

.multiselect-selected {
    /* padding-top: 5px; */
    padding-right: 5px;
    padding-bottom: 5px;
    border-bottom: 1px solid #ddd;
    max-height: 125px;
    overflow-y: scroll !important;
    background-color: #dcdcdc;
}

.multiselect-label {
    margin-left: 5px;
    margin-top: 5px;
    white-space: normal;
}

.multiselect-checkbox {
    cursor: pointer;
}

.multiselect-none-selected {
    margin-left: 5px;
    color: #545454;
    cursor: default;
}

.list-group-item.checkbox {
    /* IAM-4731: Only change the cursor on the label / checkbox itself, not the whitespace. */
    /*cursor: pointer;*/
    border: 0px solid #fff;
}
.list-group-item.checkbox:hover {
    /* IAM-4731: Do not show the different hover color. Confusing when user selects option. */
    /*background-color: #f5f5f5;*/
}

.multiselect-remove-btn {
    cursor: pointer;
}

.multiselect-list-group {
    max-height: 250px;
    overflow-y: scroll !important;
    line-height:normal;
}

/* the following two elements force the scroll bar to be shown in mac os for chrome and safari */
.multiselect-list-group::-webkit-scrollbar {
    -webkit-appearance: none;
    width: 7px;
}
.multiselect-list-group::-webkit-scrollbar-thumb {
    border-radius: 4px;
    background-color: rgba(0,0,0,.5);
    -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
}

.multiselect-selected-list-group {
    max-height: 250px;
    overflow-y: scroll !important;
    line-height:normal;
}

/* the following two elements force the scroll bar to be shown in mac os for chrome and safari */
.multiselect-selected-list-group::-webkit-scrollbar {
    -webkit-appearance: none;
    width: 7px;
}
.multiselect-selected-list-group::-webkit-scrollbar-thumb {
    border-radius: 4px;
    background-color: rgba(0,0,0,.5);
    -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
}

.multiselect-selected-list-group .list-group-item {
    border: 1px solid #D3D3D3;
    padding-top: 3px;
    padding-bottom: 5px;
}

.multiselect-selected-list-remove-icon {
    padding-right: 5px;
}

.multiselect-selected::-webkit-scrollbar {
    -webkit-appearance: none;
    width: 7px;
}
.multiselect-selected::-webkit-scrollbar-thumb {
    border-radius: 4px;
    background-color: rgba(0,0,0,.5);
    -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
}

.query-select-list-group {
    max-height: 250px;
    overflow-y: scroll !important;
    line-height:normal;
}

/* the following two elements force the scroll bar to be shown in mac os for chrome and safari */
.query-select-list-group::-webkit-scrollbar {
    -webkit-appearance: none;
    width: 7px;
}
.query-select-list-group::-webkit-scrollbar-thumb {
    border-radius: 4px;
    background-color: rgba(0,0,0,.5);
    -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
}

.query-select-list-group .list-group-item {
    border: 1px solid #D3D3D3;
    padding-top: 3px;
    padding-bottom: 5px;
}

.query-select-error {
    color: #b94a48;
    padding-left: 20px;
    padding-right: 30px;
    display:block;
}

.query-select-remove-icon {
    padding-right: 5px;
}

.list-group-item.display-item {
    border: 0px solid #fff;
}
.list-group-item.edit-item {
    cursor: pointer;
    border: 0px solid #fff;
}
.list-group-item.edit-item:hover {
    background-color: #f5f5f5;
}

.selected-users-multirequest {
    max-height: 260px;
    overflow-y: scroll !important;
    line-height:normal;
    /* border-bottom-style: solid;
border-bottom-width: 1px; */
}

/* the following two elements force the scroll bar to be shown in mac os for chrome and safari */
.selected-users-multirequest::-webkit-scrollbar {
    -webkit-appearance: none;
    width: 7px;
}
.selected-users-multirequest::-webkit-scrollbar-thumb {
    border-radius: 4px;
    background-color: rgba(0,0,0,.5);
    -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
}






.dataTables_filter {
    margin-top: 5px;
}

.dataTables_length {
    margin-top: 5px;
}

#search-existing-advanced .input-group{
    width: 50%;
}

#search-existing .form-html-padding {
    width: 100%;
}

.user-search-selected-user{
    padding-bottom:10px;
}

.user-search-search-results-panel {
    box-shadow: rgb(38, 57, 77) 7px 15px 30px -15px;
}

.user-search-tool-find-user {
    box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px;
}


.ajax-spinner {
    position: relative;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    padding: 50px;
    background: url('/icrare2/images/spinner.svg') no-repeat center;
    background-size: 80px;
}

/* ── PANEL HEADING PATTERN ────────────────────────────────────────────────────
   One heading grammar for the panels on a request page:

     [glyph]  Emphasised subject  ·  quiet qualifier          [actions/status]

   Replaces "Asset - Thing - Thing" strings joined by hyphens at uniform weight,
   where nothing read as more important than anything else. Used by the request
   flow panel and the Submitted Form panel; the middot comes from CSS so the
   markup carries no punctuation.
   ─────────────────────────────────────────────────────────────────────────── */

.ics-panel-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px 12px;
    padding: 9px 14px;
}

.ics-panel-heading-title {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.35;
    color: #1a3a5c;
}

.ics-panel-heading-icon {
    flex: 0 0 auto;
    font-size: 13px;
    color: #7d9ab5;
}

.ics-panel-heading-main,
.ics-panel-heading-main:focus {
    color: #1a3a5c;
    text-decoration: none;
    border-bottom: 1px dotted transparent;
}

a.ics-panel-heading-main:hover {
    color: #002c4e;
    text-decoration: none;
    border-bottom-color: #a8bfd4;
}

.ics-panel-heading-qualifier {
    font-size: 12.5px;
    font-weight: 500;
    color: #6b8aad;
}

.ics-panel-heading-qualifier::before {
    content: "\00b7";
    margin-right: 7px;
    color: #a8bfd4;
}

.ics-panel-heading-actions {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    gap: 8px;
}

@media (max-width: 767px) {
    .ics-panel-heading {
        align-items: flex-start;
        padding: 8px 12px;
    }

    .ics-panel-heading-title {
        font-size: 14px;
    }
}

/* ── PAGE HEADER ACTION BUTTONS ───────────────────────────────────────────────
   The row beside the page title on request details / status viewer. Was a mix
   of Bootstrap defaults: two saturated fills (btn-danger, btn-success) plus
   grey-gradient btn-defaults, all at the same size - so destructive Cancel was
   the loudest thing on the page and plain navigation competed with real actions.

   Re-weighted by what each button does:
     navigation (btn-default) - flat, hairline, recedes until hovered
     primary action (btn-success) - the only filled button
     destructive (btn-danger) - quiet until hovered, matching the subform Remove
                                and per-asset Cancel treatments

   Specificity note: custom-style.css loads after this file and restyles
   .btn-default with a grey gradient, so these rules qualify with .btn to
   outrank it (0,3,0 vs 0,1,0) rather than relying on source order.
   ─────────────────────────────────────────────────────────────────────────── */

.page-header-with-buttons .page-header-buttons {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

.page-header-buttons .btn {
    padding: 5px 11px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.45;
    border-radius: 6px;
    background-image: none;
    text-shadow: none;
    box-shadow: none;
    transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}

.page-header-buttons .btn .glyphicon,
.page-header-buttons .btn i[class*="fa-"] {
    margin-right: 4px;
    font-size: 11.5px;
}

/* Navigation: Find Requests, User's Requests, Detailed Audits, Error Dashboard */
.page-header-buttons .btn.btn-default {
    background-color: #fff;
    background-image: none;
    border-color: #d5dee8;
    color: #4f6277;
}

.page-header-buttons .btn.btn-default:hover,
.page-header-buttons .btn.btn-default:focus,
.page-header-buttons .btn.btn-default:active {
    background-color: #edf4fa;
    background-image: none;
    border-color: #a9c3da;
    color: #002c4e;
}

/* Primary action: Resubmit Request */
.page-header-buttons .btn.btn-success {
    background-color: #002c4e;
    background-image: none;
    border-color: #002c4e;
    color: #fff;
}

.page-header-buttons .btn.btn-success:hover,
.page-header-buttons .btn.btn-success:focus,
.page-header-buttons .btn.btn-success:active {
    background-color: #013e6c;
    background-image: none;
    border-color: #013e6c;
    color: #fff;
}

/* Destructive: Cancel Request. Reads red at rest so it is never mistaken for
   navigation, but a faded red - it is behind a confirm modal and does not need
   to shout. Hover deepens to the full red. */
.page-header-buttons .btn.btn-danger {
    background-color: #fdf2f1;
    background-image: none;
    border-color: #eec7c2;
    color: #b04a3d;
}

.page-header-buttons .btn.btn-danger:hover,
.page-header-buttons .btn.btn-danger:focus,
.page-header-buttons .btn.btn-danger:active {
    background-color: #f8dcd8;
    background-image: none;
    border-color: #d0554a;
    color: #a32b1c;
}

.page-header-buttons .btn[disabled],
.page-header-buttons .btn[disabled]:hover {
    background-color: #f3f5f8;
    background-image: none;
    border-color: #e2e8ef;
    color: #8a9bad;
    opacity: 1;
}

/* The "why can't I resubmit?" popover trigger sitting next to the disabled
   Resubmit button (was a -10px inline margin and a 20px inline font-size). */
.page-header-help {
    display: inline-flex;
    align-items: center;
    margin-left: 2px;
    line-height: 1;
}

/* The anchor is display:block and inherits the h1's 39.6px line-height, so the
   15px glyph sat low inside a 40px line box - centring the wrapper still left
   the glyph ~7px below the buttons. Collapsing the anchor to its content makes
   the outer align-items actually centre the glyph. */
.page-header-help > a {
    display: inline-flex;
    align-items: center;
    line-height: 1;
    color: #6b8aad;
    cursor: pointer;
}

.page-header-help > a:hover,
.page-header-help > a:focus {
    color: #002c4e;
}

.page-header-help .glyphicon {
    font-size: 15px;
    line-height: 1;
    /* Bootstrap's relative top:1px nudges glyphs onto a text baseline; there is
       no baseline to meet inside a flex row. */
    top: 0;
}

/* ── MODAL HEADERS ───────────────────────────────────────────────────────────
   Originally from https://bootsnipp.com/snippets/featured/colored-modal-headings
   (Bootstrap 3's #428bca, plus vendor-prefixed radii no supported browser
   needs). Now two variants sharing one geometry:

     primary - the light tint used by .panel-primary > .panel-heading, so a
               modal heading reads the same as a panel heading
     danger  - filled red, for modals reporting a failure

   The two are deliberately different weights: routine modals recede, failures
   announce themselves.
   ─────────────────────────────────────────────────────────────────────────── */

.modal-header-primary,
.modal-header-danger {
    padding: 9px 15px;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
}

/* Matches .panel-primary > .panel-heading above. */
.modal-header-primary {
    background-color: #f0f4f8;
    background-image: none;
    color: #1a3a5c;
    /* The panel version has no bottom border - its body is #fafafa, so the tint
       alone separates them. A modal body is white, which is close enough to the
       tint to need a hairline. */
    border-bottom: 1px solid #e2e9f0;
}

.modal-header-primary .modal-title {
    color: #1a3a5c;
    font-weight: 600;
}

.modal-header-danger {
    background-color: #c0392b;
    color: #fff;
    border-bottom: 1px solid #eee;
}

.modal-header-danger .modal-title {
    color: #fff;
}

/* Bootstrap's .close is black at 0.2 opacity - invisible on the filled red
   header, and weak on the tinted one. Each variant gets a legible treatment. */
.modal-header-primary .close {
    color: #1a3a5c;
    opacity: 0.5;
    text-shadow: none;
}

.modal-header-primary .close:hover,
.modal-header-primary .close:focus {
    color: #002c4e;
    opacity: 1;
}

.modal-header-danger .close {
    color: #fff;
    opacity: 0.8;
    text-shadow: none;
}

.modal-header-danger .close:hover,
.modal-header-danger .close:focus {
    color: #fff;
    opacity: 1;
}

.icsynergy-input[disabled] {
    color:black;
    z-index: 0;
}

/* fix modal issue with inputs not greying out in the background  */
.input-group .form-control {
    z-index: 0;
}

.list-group-item.checkbox.disabled {
    color:black;
}

.icsynergy-change-icon {
    cursor: pointer;
}

.subform-panel{
    /*padding: 10px;*/
}

/* Used in hr class='form-line-break' to give a pronounced line break in a form.
   Now a hairline in the palette rather than a solid #27639C bar - see the
   separator handling in the FORM BUILDER REFRESH block, which this matches.

   Sole definition of the class: the refresh block used to redeclare it further
   down with background-color + border:0, and being later it won the cascade and
   reset the border-top set here - leaving a zero-height element with nothing to
   paint. Inside a form the blanket .icsynergy-form hr rule still drew a
   hairline, so the loss only showed on the report templates
   (login_expiry_report and friends), which use the class outside any form.
   Heading-specific spacing lives with the heading rules, not here. */
.form-line-break {
    width: 100%;
    height: 0;
    border: 0;
    border-top: 1px solid #d5dee8;
    background-color: transparent;
    margin-top: 8px;
    margin-bottom: 0;
}

.user-popover-box {
    width:450px;
    height:210px;
    overflow-y: scroll;
    position:relative
}

.user-popover-box-wrap {
    word-wrap: break-word;
}

.user-expansion-popover .popover-title {
    position: relative;
}

.user-expansion-popover-close {
    background: transparent;
    border: 0;
    cursor: pointer;
    display: none;
    font-size: 18px;
    line-height: 1;
    padding: 0;
    position: absolute;
    right: 0;
    top: 0;
}

@media (max-width: 767px) {
    .user-expansion-popover {
        left: 50% !important;
        max-width: calc(100vw - 16px) !important;
        transform: translateX(-50%);
        width: calc(100vw - 16px);
    }

    .user-expansion-popover .arrow {
        display: none;
    }

    .user-expansion-popover-close {
        display: block;
    }

    .user-expansion-popover .popover-content {
        padding: 12px;
    }

    .user-popover-box {
        height: auto;
        max-height: 60vh;
        overflow-x: hidden;
        overflow-y: auto;
        width: 100%;
    }

    .user-expansion-popover .text-center .btn {
        margin-bottom: 6px;
        white-space: normal;
    }
}

.user-details-header {
    font-size: 12px;
    font-weight: bold;
    color: #959595;
    text-transform: uppercase;
    letter-spacing: 1px;
}

.user-details-dl dt {
    color: #666666;
}

.dropdown-header {
    font-size: 12px;
    font-weight: bold;
    color: #959595;
    text-transform: uppercase;
    letter-spacing: 1px;
    padding-top:10px;
    padding-left:5px;
}

/**
    Disable any element by making it not clickable and adding an opaque-ness to it.
 */
.disabled {
    pointer-events:none;
    opacity:0.6;
}



/**
    This is to support left-aligned glypicons in text boxes (See login page)
    https://stackoverflow.com/a/18839305
 */
.has-feedback .form-control {
    padding-right: 34px;
}
.has-feedback .form-control.input-sm,
.has-feedback.form-group-sm .form-control {
    padding-right: 30px;
}
.has-feedback .form-control.input-lg,
.has-feedback.form-group-lg .form-control {
    padding-right: 46px;
}
.has-feedback-left .form-control {
    padding-right: 12px;
    padding-left: 34px;
}
.has-feedback-left .form-control.input-sm,
.has-feedback-left.form-group-sm .form-control {
    padding-left: 30px;
}
.has-feedback-left .form-control.input-lg,
.has-feedback-left.form-group-lg .form-control {
    padding-left: 46px;
}
.has-feedback-left .form-control-feedback {
    left: 0;
}
.form-control-feedback {
    line-height: 34px !important;
}
.input-sm + .form-control-feedback,
.form-horizontal .form-group-sm .form-control-feedback {
    width: 30px;
    height: 30px;
    line-height: 30px !important;
}
.input-lg + .form-control-feedback,
.form-horizontal .form-group-lg .form-control-feedback {
    width: 46px;
    height: 46px;
    line-height: 46px !important;
}
.has-feedback label.sr-only ~ .form-control-feedback,
.has-feedback label.sr-only ~ div .form-control-feedback {
    top: 0;
}
@media (min-width: 768px) {
    .form-inline .inline-feedback {
        position: relative;
        display: inline-block;
    }
    .form-inline .has-feedback .form-control-feedback {
        top: 0;
    }
}
.form-horizontal .has-feedback-left .form-control-feedback {
    left: 15px;
}

/* LOGIN SHADOW */
.login-box-shadow {
    -webkit-box-shadow: 10px 10px 48px -10px rgba(79,79,79,0.69);
    -moz-box-shadow: 10px 10px 48px -10px rgba(79,79,79,0.69);
    box-shadow: 0px 0px 48px -10px rgba(79,79,79,0.69) /* this one is different to support IE */
}

.login-page-header {
    color: #002c4e;
    margin:20px 0 20px;
}

.sspr-page-header {
    color: #002c4e;
    padding-bottom: 1px;
    margin: 1px 0 1px;
}

/* Fixed table headers */
.tableFixHead    { overflow-y: auto; height: 100px; }
.tableFixHead th { position: sticky; top: 0; background-color:#f9f9f9;}

.ics-changed-field {
    /*    background: url('/portal/images/warning-sml-3e01bcff8c79bb031c9ddfb4c1ce1a7f.jpg');*/
    width:17px;
    height:17px;
}
/* Search */
.search-wrap { position: sticky; top: 0; z-index: 5; background: #fff; border-bottom: 1px solid #e6eaee; padding: 10px 15px; }
.search-input { width: 100%; }

/* Entitlement pills */
/* The scrollable region */
.entitlements-scroll {
    max-height: 400px;                 /* or: calc(100vh - 360px) */
    overflow: auto;
    padding: 12px;
    /*border: 1px solid #e5e5e5;*/
    border: 0px;
    border-radius: 4px;
    background: #fff;
    /* show scrollbar */
    
}
.entitlement-search {
    position: sticky;
    position: -webkit-sticky;    /* better Safari support */
    top: 0;
    z-index: 3;                   /* above the pills */
    background: #fff;             /* hide content scrolling under it */
    padding: 8px 0 10px;
    margin: -8px 0 8px;          /* pull up to the container padding */
    border-bottom: 1px solid #e5e5e5;
    box-shadow: 0 1px 0 rgba(0,0,0,0.03);
}

.pill-grid {

}

.entitlement-pill {
    position:relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border-radius: 15px;
    color: #0a4e78;
    cursor: pointer;
    user-select: none;
}
.entitlement-pill-with-background {
    background: #e8f1f7;
    margin-bottom: 5px;
}

.entitlement-pill-with-background.disabled {
    background: #ccc;
}
/*.entitlement-pill {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    border-radius: 20px;
    background: #e8f1f7;
    color: #0a4e78;
    border: 1px solid #cfe3f2;
    cursor: pointer;
    user-select: none;
    margin-bottom:5px;
}*/
.entitlement-pill .title { font-weight: 600; }
.entitlement-pill:hover { background: #dff0fb; }

/* Label inside disabled pill */
.entitlement-pill.warning  .title {
    color: #666;
    cursor: not-allowed;
}

.entitlement-pill.warning {
    background: #ffeca1;
    color: #000;
    cursor: not-allowed;
    margin: 2px;    
}

.entitlement-pill.pending {
    background: #f0f0f0;
    color: #000;
    cursor: not-allowed;
    margin: 2px;
}

/* Info icon always active */
.entitlement-pill .info-btn {
    margin-left: 6px;
    cursor: pointer;
    color: #0a4e78;
    pointer-events: auto;
    z-index: 2;
}

/*.info-block {
    display: none;
    position: absolute;
    left:100%;
    right: 0;
    margin-bottom: 10px;
    min-width: 240px;
    background: #fff;
    color: #000;
    border: 1px solid #ccc;
    border-radius: 10px;
    padding: 12px;
    box-shadow: 0 4px 10px rgba(0,0,0,0.15);
    z-index: 300;
    word-wrap: break-word;
} */

/*.info-block h4 {
    margin: 0 0 6px;
    font-size: 14px;
    font-weight: bold;
    color: #000;
}*/

/*.info-block p {
    margin: 0;
    font-size: 13px;
    color: #333;
} */
/* automatically size to content */
/*.info-block.auto-size {
    width: max-content;
    max-width: 240px;
}*/

/* Selected state */
.entitlement-pill.selected { background: #002c4e; color: #fff; border-color: #002c4e; margin:2px;}
.entitlement-pill.selected .info-btn { color: #fff; opacity: .85; }
.entitlement-pill .check { display: none; }
.entitlement-pill.selected .check { display: inline-block; }
.entitlement-pill.selected .available-asset-access-btn {
    display: none;
}

/* Section headers */
.section-header { padding: 10px 15px; margin: 0; border-top: 1px solid #e6eaee; color: #4a5568; font-weight: 600; text-transform: uppercase; font-size: 12px; background: #fafcfd; }

/* Floating selection badgeContainer */
.badgeContainer { position: sticky; top:30px; }
.badgeContainer .panel { border: 0px;}
/*.badgeContainer .selected-badges { background: #0078ae; color: #fff; border-color: #0078ae; }*/
.badgeContainer .badge-pill {
    display: block;
    background: #002c4e;
    color: #fff;
    border: 1px solid rgba(255,255,255,.25);
    padding: 3px 5px;
    border-radius: 8px;
    margin-bottom: 5px;
    font-size: small;
}
.badgeContainer .badge-pill .remove { margin-right: 8px; cursor: pointer; }
.badgeContainer .badge-pill .info-btn { margin-left: 6px; cursor: pointer; }
.badgeContainer .actions { text-align: right; }

/* Warning glyph  */
.global-warning-icon {color: #f0ad4e; /* orange */cursor: pointer;}

.entitlement-view-tabs{
    margin: 5px;
}
.selected-badges .info-block{
    display: none;
    position: absolute;
    left:20%;
    right: 0;
    margin-bottom: 10px;
    min-width: 140px;
    background: #fff;
    color: #000;
    border: 1px solid #ccc;
    border-radius: 10px;
    padding: 12px;
    box-shadow: 0 4px 10px rgba(0,0,0,0.15);
    z-index: 200;
    white-space: normal;
    word-wrap: break-word;
}

.empty-message {
    display: inline-block;
    text-align: left;
    font-style: italic;
    padding: 10px 16px;
    border: 1px dashed #ccc;
    border-radius: 8px;
    background-color: #f9f9f9;
    margin: 10px 0 0 15px;        /* adds left offset under tab */
}

.empty-message i {
    margin-right: 6px;
}

.available-asset-access-btn{
    margin-right:5px;
}

.home-data-table thead th {
    border-bottom-width: 2px;
}

.home-data-table tbody tr {
    transition: background-color 0.16s ease, box-shadow 0.16s ease;
}

.home-data-table tbody tr + tr td {
    border-top-color: #e6edf5;
}

.home-data-table tbody tr:hover td,
.home-data-table tbody tr:focus-within td {
    background-color: #f7fbff;
}

.home-action-cell {
    white-space: nowrap;
}

/* ── DRAFT REQUEST ROW ACTIONS ────────────────────────────────────────────────
   Resume and Delete on the home page draft list. Both were saturated Bootstrap
   fills (btn-primary, btn-danger), so a row of drafts read as a wall of solid
   blue and red - louder than the request data beside it.

   Same re-weighting as the page header buttons above:
     Resume (btn-primary) - flat outline, navy ink, fills only on hover
     Delete (btn-danger)  - faded red at rest, full red on hover

   Specificity note: custom-style.css loads after this file and restyles the
   Bootstrap button classes with gradients, so these rules qualify with .btn
   to outrank it (0,3,0 vs 0,1,0) rather than relying on source order.
   ─────────────────────────────────────────────────────────────────────────── */

.draft-action-group {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

.draft-action-group .btn {
    padding: 4px 10px;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.45;
    border-radius: 6px;
    background-image: none;
    text-shadow: none;
    box-shadow: none;
    transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}

.draft-action-group .btn i[class*="fa-"] {
    font-size: 11.5px;
}

.draft-action-group .btn.btn-primary {
    background-color: #fff;
    background-image: none;
    border-color: #d5dee8;
    color: #0a4e78;
}

.draft-action-group .btn.btn-primary:hover,
.draft-action-group .btn.btn-primary:focus,
.draft-action-group .btn.btn-primary:active {
    background-color: #edf4fa;
    background-image: none;
    border-color: #a9c3da;
    color: #002c4e;
}

/* Disabled Resume: the draft's subject is deleted or unknown. Bootstrap 3 puts
   .disabled on the anchor, which does not take [disabled], so match both. */
.draft-action-group .btn.btn-primary.disabled,
.draft-action-group .btn.btn-primary[disabled],
.draft-action-group .btn.btn-primary.disabled:hover,
.draft-action-group .btn.btn-primary[disabled]:hover {
    background-color: #f3f5f8;
    background-image: none;
    border-color: #e2e8ef;
    color: #8a9bad;
    opacity: 1;
}

.draft-action-group .btn.btn-danger {
    margin-left: 6px;
    background-color: #fdf2f1;
    background-image: none;
    border-color: #eec7c2;
    color: #b04a3d;
}

.draft-action-group .btn.btn-danger:hover,
.draft-action-group .btn.btn-danger:focus,
.draft-action-group .btn.btn-danger:active {
    background-color: #f8dcd8;
    background-image: none;
    border-color: #d0554a;
    color: #a32b1c;
}

.home-asset-table tbody tr td {
    border-top-color: #e6edf5;
}

.home-asset-table tbody tr:hover td,
.home-asset-table tbody tr:focus-within td {
    background-color: #f7fbff;
}

/* ── Multi-request available assets table ────────────────────────────── */
.multi-request-assets-table {
    width: 100%;
    border-collapse: collapse;
}

.multi-request-assets-table td {
    padding: 9px 16px;
    border-top: 1px solid #eef2f7;
    vertical-align: middle;
}

.multi-request-assets-table tbody tr:first-child td {
    border-top: none;
}

.multi-request-assets-table tbody tr:hover td {
    background-color: #f7fbff;
}

/* The info cell shrinks to a fixed content width, so the action button always
   sits directly beside the entitlement name instead of at the page edge. */
.entitlement-select-info {
    width: 1%;
}

.entitlement-select-line {
    position: relative;
    width: 26rem;
    max-width: 100%;
}

.entitlement-select-name {
    display: inline-block;
    max-width: calc(100% - 24px);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
    font-size: 13px;
    font-weight: 600;
    color: #1a3a5c;
}

.entitlement-select-line .info-btn {
    margin-left: 6px;
    vertical-align: middle;
    cursor: pointer;
    color: #0a4e78;
}

.entitlement-select-line .info-btn:hover,
.entitlement-select-line .info-btn:focus {
    color: #002c4e;
}

.entitlement-select-info-block {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 300;
    width: max-content;
    max-width: 26rem;
    margin-top: 4px;
    padding: 8px 12px;
    background: #fff;
    border: 1px solid #ccd6e0;
    border-radius: 6px;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
    font-size: 12px;
    font-weight: normal;
    color: #333;
    white-space: normal;
    word-wrap: break-word;
}

.entitlement-select-action {
    width: auto;
    white-space: nowrap;
    text-align: left;
    padding-left: 8px;
}

/* On narrow screens the fixed info width would overflow, so stack the row. */
@media (max-width: 767px) {
    .multi-request-assets-table td {
        display: block;
        padding: 4px 16px;
    }

    .multi-request-assets-table td.entitlement-select-info {
        padding-top: 9px;
    }

    .multi-request-assets-table td.entitlement-select-action {
        padding-bottom: 9px;
        padding-left: 16px;
        border-top: none;
    }
}

/* ── Entitlement Home List (with action buttons) ─────────────────────── */
.entitlement-home-list {
    padding: 4px 0;
}

.entitlement-home-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 9px 16px;
    border-bottom: 1px solid #eef2f7;
    transition: background-color 0.12s;
}

.entitlement-home-row:last-child {
    border-bottom: none;
}

.entitlement-home-row:hover {
    background-color: #f7fbff;
}


.entitlement-home-info {
    flex: 1;
    min-width: 0;
}

.entitlement-home-name {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: #1a3a5c;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.entitlement-home-desc {
    display: block;
    font-size: 11.5px;
    color: #6b8aad;
    margin-top: 1px;
}

.entitlement-home-maint {
    margin: 4px 0 0;
    padding: 4px 8px;
    font-size: 12px;
}

.entitlement-home-action {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

.entitlement-home-status-badge {
    font-size: 11px;
    font-weight: 600;
    color: #27ae60;
    white-space: nowrap;
}

/* ── Entitlement Home Tags (display-only, no buttons) ────────────────── */
.entitlement-home-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 14px 16px;
}

.entitlement-home-tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: #eef5fb;
    border: 1px solid #cfe2f3;
    border-radius: 20px;
    padding: 5px 13px;
    font-size: 12.5px;
    color: #1a3a5c;
    font-weight: 500;
}

.entitlement-home-tag-icon {
    font-size: 11px;
    color: #27ae60;
}

.entitlement-home-tag-desc {
    font-size: 11px;
    color: #6b8aad;
    font-weight: 400;
}

.request-status-row + .request-status-row {
    margin-top: 6px;
}

.request-status-asset-name {
    display: inline;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
}

.request-status-flow-name {
    font-size: 11px;
    color: #6b8aad;
    font-weight: 400;
    margin-left: 2px;
}

.request-status-flow-name::before {
    content: "·";
    margin-right: 4px;
    color: #a8bfd4;
}

.request-status-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border: 1px solid transparent;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.2;
    vertical-align: middle;
}

.request-status-pill i {
    font-size: 12px;
}

.request-status-pill-denied {
    background-color: #fbe9e9;
    border-color: #efc4c4;
    color: #9f2f2f;
}

.request-status-pill-pending {
    background-color: #fff6df;
    border-color: #f0d99a;
    color: #8a6516;
}

.request-status-pill-completed {
    background-color: #e7f4ea;
    border-color: #bddfca;
    color: #256b3a;
}

.request-status-pill-neutral {
    background-color: #eef3f8;
    border-color: #d5dee8;
    color: #4f6277;
}

@media (max-width: 767px) {
    .home-layout-row {
        display: flex;
        flex-direction: column;
    }

    .home-sidebar-column {
        order: -1;
    }

    .home-content-column {
        order: 1;
    }
}

/* ── Welcome Banner ──────────────────────────────────────────────────────── */
@media (max-width: 767px) {
    .welcome-inner {
        flex-direction: column;
        align-items: flex-start;
        padding: 16px 16px;
        gap: 16px;
    }

    .welcome-cards {
        flex-wrap: wrap;
        width: 100%;
    }

    .welcome-card {
        flex: 1 1 calc(50% - 7px);
        min-width: 0;
        padding: 14px 10px;
    }

    .welcome-name {
        font-size: 20px;
    }
}

.welcome-banner {
    background: linear-gradient(120deg, #eef5fb 0%, #f5f9ff 60%, #fff 100%);
    border: 1px solid #cfe2f3;
    border-left: 5px solid #2872b0;
    border-radius: 8px;
    margin-bottom: 22px;
    padding: 0;
    overflow: hidden;
}

.welcome-inner {
    display: flex;
    align-items: center;
    padding: 14px 20px;
    gap: 20px;
}

.welcome-left {
    flex-shrink: 0;
}

.welcome-name {
    font-size: 24px;
    font-weight: 700;
    color: #1a3a5c;
    line-height: 1.2;
    margin-bottom: 5px;
    font-family: 'DM Sans', 'Inter', sans-serif;
}

.welcome-subtitle {
    font-size: 13px;
    color: #6b8aad;
    font-weight: 400;
}

.welcome-cards {
    display: flex;
    gap: 8px;
    flex-wrap: nowrap;
    flex: 1;
}

.welcome-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 8px 14px;
    background: #fff;
    border: 1px solid #d6e8f8;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(40, 114, 176, 0.07);
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    transition: box-shadow 0.18s ease, transform 0.18s ease, border-color 0.18s ease;
    min-width: 80px;
}

.welcome-card:hover,
.welcome-card:focus {
    box-shadow: 0 4px 14px rgba(40, 114, 176, 0.18);
    transform: translateY(-2px);
    border-color: #2872b0;
    text-decoration: none;
    color: inherit;
    outline: none;
}

.welcome-card-icon {
    font-size: 18px;
    color: #2872b0;
    margin-bottom: 3px;
    line-height: 1;
}

.welcome-card-count {
    font-size: 18px;
    font-weight: 700;
    color: #1a3a5c;
    line-height: 1;
    margin-bottom: 2px;
    font-family: 'DM Sans', 'Inter', sans-serif;
}

.welcome-card-label {
    font-size: 10px;
    color: #6b8aad;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    font-weight: 600;
    text-align: center;
    white-space: nowrap;
}

/* Home navigation buttons — styled to match welcome banner cards */
.home-nav-buttons {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 0 0 15px 0;
}

.home-nav-btn {
    display: flex;
    align-items: center;
    padding: 10px 14px;
    background: #fff;
    border: 1px solid #d6e8f8;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(40, 114, 176, 0.07);
    text-decoration: none;
    color: #1a3a5c;
    transition: box-shadow 0.18s ease, transform 0.18s ease, border-color 0.18s ease;
    font-size: 14px;
    font-weight: 500;
    gap: 10px;
}

.home-nav-btn:hover,
.home-nav-btn:focus {
    box-shadow: 0 4px 14px rgba(40, 114, 176, 0.18);
    transform: translateY(-2px);
    border-color: #2872b0;
    text-decoration: none;
    color: #1a3a5c;
    outline: none;
}

.home-nav-btn-icon {
    font-size: 16px;
    color: #2872b0;
    line-height: 1;
    flex-shrink: 0;
}

.home-nav-btn-label {
    flex: 1;
    min-width: 0;
}

.home-nav-btn-accent {
    font-weight: 600;
}

.home-nav-divider {
    margin: 6px 0;
    border-color: #d6e8f8;
}

/* Tighten the gutter between the sidebar buttons and the main content so
   badges inside the buttons don't overflow when viewport is narrow
   (e.g. ~1050px with the sidebar expanded). */
@media (min-width: 992px) {
    .home-sidebar-column {
        padding-right: 4px;
    }
    .home-content-column {
        padding-left: 4px;
    }
    .home-nav-btn {
        padding: 10px 10px;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   FORM BUILDER REFRESH
   ═══════════════════════════════════════════════════════════════════════════
   Presentation-only pass over the form builder forms and widgets, bringing
   them into the same visual language as the catalog / home pages above
   (navy #002c4e, #1a3a5c headings, #eef2f7 hairlines, 999px pills,
   #f7fbff hover).

   Deliberately CSS-only. form.js is tightly coupled to the rendered DOM -
   .find(".widget-wrapper").parent().parent().html(data) for field refresh,
   .closest(".panel-title") for the subform remove spinner,
   .icsynergy-subforms > div counting for subform indexes - so no template
   restructuring is involved and nothing here changes the box tree.

   Everything is scoped to .icsynergy-form (every form and subform) or to a
   widget's own class, so no other page picks these up.

   Input border-radius is intentionally left at the Bootstrap 3 default:
   raising it breaks the joined corners of .input-group (datepicker,
   multitext, every search box).
   ══════════════════════════════════════════════════════════════════════════ */

:root {
    --fb-ink:          #1a3a5c;   /* headings, label text */
    --fb-ink-muted:    #6b8aad;   /* secondary text */
    --fb-navy:         #002c4e;   /* primary accent */
    --fb-link:         #0a4e78;   /* interactive text */
    --fb-hairline:     #eef2f7;   /* row separators */
    --fb-border:       #d5dee8;   /* container borders */
    --fb-tint:         #f0f4f8;   /* header / bar fill */
    --fb-tint-soft:    #f7fbff;   /* hover fill */
    --fb-pill-bg:      #e8f1f7;   /* selected pill fill */
    --fb-pill-border:  #cfe3f2;
    --fb-danger:       #c0392b;
    --fb-rail:         #b9cadb;   /* subform accent rail, default state */

    /* Caution tone, for notices that warn without being errors. Swap these three
       for the --fb-danger family if a notice really should read as an error. */
    --fb-warn-rail:    #d99f2b;
    --fb-warn-tint:    #fdf8ec;
    --fb-warn-ink:     #5c4a20;

    /* Density. AHS users are commonly on short laptop screens, so the form
       builder runs tighter than stock Bootstrap 3 (which spends 15px of margin
       per row and 34px of height per control). Dial these four to retune the
       whole form builder at once. */
    --fb-row-gap:      8px;       /* vertical gap between field rows */
    --fb-control-h:    30px;      /* single-line control height (was 34px) */
    --fb-pad-y:        6px;       /* panel header / bar vertical padding */
    --fb-pad-x:        10px;      /* panel header / bar horizontal padding */
}

/* ── Outer asset panel ──────────────────────────────────────────────────── */

#form-contents .panel-primary,
#form-contents .panel-info,
#form-contents .panel-default {
    border-radius: 8px;
}

#form-contents > div > .panel > .panel-heading {
    padding: 8px 14px;
}

#form-contents > div > .panel > .panel-body {
    padding: 12px 14px;
}

#form-contents .panel-primary .panel-title {
    font-size: 15px;
    color: var(--fb-ink);
    letter-spacing: 0.1px;
}

/* ── Field rhythm ───────────────────────────────────────────────────────── */

.icsynergy-form .form-row.form-group {
    /* style.css also puts margin-top: 5px on .form-row; the gap is expressed
       once, on the bottom. */
    margin-top: 0;
    margin-bottom: var(--fb-row-gap);
}

/* Rows holding nothing but a HiddenInput still cost a full row margin each.
   They would otherwise self-collapse to nothing, but the request form is
   .form-horizontal, whose .form-group clearfix gives every row real height -
   so each one bills its full 5px top + 15px bottom. ANP-Facilities opens with
   eight, putting ~160px of void above the first real field of every facility
   subform. The ANP initial step measures 18 such rows / 144px.

   The "> *" is the unclassed div that _label_and_widget's fragment root
   contributes between the row and .widget-wrapper - do not remove it. A HiddenInput is the only
   widget whose .icsynergy-field contains a lone hidden input - Label and the
   disabled-field value carriers always have a visible sibling - so :only-child
   identifies these rows exactly. Progressive enhancement: browsers without
   :has() just keep the old spacing. */
.icsynergy-form .form-row.form-group:has(> * > .widget-wrapper > .icsynergy-field > input[type="hidden"]:only-child) {
    margin-top: 0;
    margin-bottom: 0;
}

/* No overflow/containment on .widget-wrapper: help popovers and the advanced
   search operand dropdown are inserted next to their trigger inside it, so
   any clipping context here cuts them off. */

/* ── Labels ─────────────────────────────────────────────────────────────── */

.icsynergy-form .control-label > label {
    font-size: 13px;
    font-weight: 600;
    color: var(--fb-ink);
    line-height: 1.35;
    padding-top: 0;
    margin-bottom: 1px;
}

.icsynergy-form .col-sm-2.control-label {
    padding-top: 6px;
}

.icsynergy-form .required-asterisk-glyph {
    color: #d64545;
    font-size: 7px;
    top: -4px;
    margin-right: 2px;
}

.icsynergy-form .icsynergy-help-popover {
    color: var(--fb-ink-muted);
    transition: color 0.12s;
}

.icsynergy-form .icsynergy-help-popover:hover,
.icsynergy-form .icsynergy-help-popover:focus {
    color: var(--fb-navy);
    text-decoration: none;
}

.icsynergy-form .icsynergy-change-icon .ics-changed-field {
    width: 14px;
    height: 14px;
    opacity: 0.85;
}

/* ── Inputs ─────────────────────────────────────────────────────────────── */

.icsynergy-form .form-control {
    border-color: var(--fb-border);
    box-shadow: none;
    transition: border-color 0.12s, box-shadow 0.12s;
}

/* Shorter controls. Height is set on the three input-group participants
   together so the datepicker, multitext and search boxes stay flush. */
.icsynergy-form input.form-control,
.icsynergy-form select.form-control:not([multiple]),
.icsynergy-form .input-group-addon,
.icsynergy-form .input-group-btn > .btn {
    height: var(--fb-control-h);
    padding-top: 3px;
    padding-bottom: 3px;
    font-size: 13px;
    line-height: 1.5;
}

.icsynergy-form textarea.form-control {
    height: auto;
    padding: 5px 10px;
    font-size: 13px;
}

.icsynergy-form select.form-control:not([multiple]) {
    /* Bootstrap 3 pins select line-height to the old 34px. */
    line-height: calc(var(--fb-control-h) - 8px);
}

.icsynergy-form .form-control:hover:not([disabled]) {
    border-color: #b9c7d7;
}

.icsynergy-form .form-control:focus,
.icsynergy-form .panel-body .form-control:focus {
    border-color: var(--fb-navy);
    box-shadow: 0 0 0 3px rgba(0, 44, 78, 0.12);
}

.icsynergy-form textarea.form-control {
    line-height: 1.45;
    resize: vertical;
}

.icsynergy-form .form-control[disabled],
.icsynergy-form .icsynergy-input[disabled] {
    background-color: #f3f5f8;
    border-color: #d3dbe4;
    color: #46586e;
    cursor: not-allowed;
    opacity: 1;
}

.icsynergy-form .input-group-addon {
    background-color: var(--fb-tint);
    border-color: var(--fb-border);
    color: var(--fb-ink-muted);
}

/* Help text for the option currently chosen in a Select. The block is always in the
   markup so its id stays stable for aria-describedby; :empty is what hides it, so
   nothing has to toggle a class as the selection changes. MySchedule's role help runs
   to ~420 characters, so this is sized to be read as a short paragraph rather than
   squeezed onto one line.

   pre-line is what lets help text be multi-line: the string is plain text (it doubles
   as the option's title attribute, which cannot take markup), so its \n would
   otherwise collapse to a space and run the lines together. Measured: pre-line breaks
   the lines identically whether the block was filled server-side by th:text or at
   runtime by form.js's .text(). Spaces still collapse, so authored indentation in a
   config or DB value does not leak through. */
.icsynergy-form .select-option-help {
    margin: 4px 0 0;
    padding: 6px 9px;
    border-left: 2px solid var(--fb-pill-border);
    background-color: var(--fb-tint-soft);
    font-size: 12px;
    line-height: 1.5;
    color: #46586e;
    max-width: 60em;
    white-space: pre-line;
}

.icsynergy-form .select-option-help:empty {
    display: none;
}

/* ── Inline field notices ───────────────────────────────────────────────────
   Prose a rules class emits into an html Label, next to the field it is about -
   the NAR sunset-date warning (NarRulesSunsetDateHelper.sunsetWarningText) is
   the first user. Same geometry, type and rail as .select-option-help above, so
   everything that explains a field reads as one family; only the tone changes.

   This exists so rules classes stop styling their own output inline
   (<p style='color: red'>): an inline style is unreachable from here, and red
   read as an error on a form where nothing was wrong yet.
   ─────────────────────────────────────────────────────────────────────────── */

.icsynergy-form .form-inline-note {
    margin: 4px 0 0;
    padding: 7px 10px 8px;
    border: 1px solid var(--fb-hairline);
    border-left: 2px solid var(--fb-navy);
    border-radius: 4px;
    background-color: #fff;
    font-size: 12px;
    line-height: 1.5;
    color: #46586e;
    max-width: 60em;
}

/* Caution tone: same block, warmer. The base is the neutral one, so a notice has
   to opt in to looking like a warning. */
.icsynergy-form .form-inline-note-warning {
    border-color: #f0e2c4;
    border-left-color: var(--fb-warn-rail);
    background-color: var(--fb-warn-tint);
    color: var(--fb-warn-ink);
}

/* First line names the situation; the body explains it. */
.icsynergy-form .form-inline-note-title {
    display: block;
    margin-bottom: 3px;
    font-weight: 600;
    color: var(--fb-navy);
}

.icsynergy-form .form-inline-note-warning .form-inline-note-title {
    color: var(--fb-warn-ink);
}

.icsynergy-form .form-inline-note-icon {
    margin-right: 5px;
    font-size: 11px;
    top: 1px;
    color: var(--fb-navy);
}

.icsynergy-form .form-inline-note-warning .form-inline-note-icon {
    color: var(--fb-warn-rail);
}

/* A caveat that qualifies the notice above it ("however, as an Account
   Administrator...") - set off by a hairline rather than by another heading, so
   it does not compete with the title. */
.icsynergy-form .form-inline-note-aside {
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid var(--fb-hairline);
    font-weight: 600;
}

.icsynergy-form .form-inline-note-warning .form-inline-note-aside {
    border-top-color: #f0e2c4;
}

/* Paragraphs, so the text wraps to the box instead of being broken by authored
   <br/>s at whatever width the field happens to be. */
.icsynergy-form .form-inline-note p {
    margin: 0;
}

.icsynergy-form .form-inline-note p + p {
    margin-top: 4px;
}

/* Read-only label widget values sit on the same baseline as real inputs. */
.icsynergy-form .form-control-static {
    padding-top: 6px;
    color: #33475b;
    min-height: 20px;
}

/* Whole field is dimmed while form.js is fetching a remote refresh
   (it toggles .disabled on .icsynergy-field around the AJAX call). */
.icsynergy-form .icsynergy-field.disabled {
    opacity: 0.5;
    transition: opacity 0.15s;
}

/* ── Validation ─────────────────────────────────────────────────────────── */

.icsynergy-form .parsley-errors-list {
    list-style: none;
    padding: 0;
    margin: 2px 0 0;
    font-size: 12px;
    line-height: 1.4;
    color: var(--fb-danger);
}

.icsynergy-form .parsley-errors-list:empty {
    margin: 0;
}

.icsynergy-form input.parsley-error,
.icsynergy-form select.parsley-error,
.icsynergy-form textarea.parsley-error {
    border-color: #e0a8a2;
    background-color: #fffafa;
    box-shadow: 0 0 0 3px rgba(192, 57, 43, 0.09);
}

.icsynergy-form input.parsley-success,
.icsynergy-form select.parsley-success,
.icsynergy-form textarea.parsley-success {
    border-color: #bddfca;
    background-color: #fff;
    box-shadow: none;
}

/* ── Checkboxes and radios ──────────────────────────────────────────────── */

/* G1. Every checkbox and radio in the product rendered in the browser's default
   blue while everything around it was AHS navy. accent-color recolours the
   native control without replacing it, so the real input stays in the DOM and
   form.js keeps working against it - no wrapper markup, no pseudo-element
   substitution, no change to how :checked is read.

   Applies to the Checkbox and Radio widgets, MultiSelect options, and Select
   All. Browsers without accent-color support fall back to their default,
   which is the current behaviour. */
.icsynergy-form input[type="checkbox"],
.icsynergy-form input[type="radio"] {
    accent-color: var(--fb-navy);
}

.icsynergy-form .checkbox,
.icsynergy-form .radio {
    margin-top: 2px;
    margin-bottom: 2px;
}

.icsynergy-form .checkbox > label,
.icsynergy-form .radio > label {
    font-size: 13px;
    color: #33475b;
    line-height: 1.45;
}

/* ── Keyboard focus ─────────────────────────────────────────────────────────
   G4. There was no :focus-visible anywhere in the codebase, so keyboard focus
   fell back to whatever Bootstrap 3 left behind - a thin dotted outline that
   fires on :focus, which means it also appeared after a mouse click. Hence the
   two halves of this section: suppress the dotted ring on pointer interaction,
   then put a real ring back for keyboard users only.

   Text inputs are deliberately excluded: .form-control:focus already gets a
   border + shadow treatment further up, and adding an outline on top of it
   double-rings the field. */

.icsynergy-form .btn:focus,
.icsynergy-form a:focus,
.icsynergy-form .close:focus {
    outline: none;
}

.icsynergy-form .btn:focus-visible,
.icsynergy-form a:focus-visible,
.icsynergy-form .close:focus-visible {
    outline: 2px solid var(--fb-link);
    outline-offset: 2px;
    border-radius: 3px;
}

/* Option rows own the focus ring rather than the 13px checkbox inside them.
   Reuses the hover fill so keyboard and pointer traversal read the same, with
   an inset rail marking which row focus is actually on. Falls back to the
   browser's own ring on the checkbox where :has() is unsupported. */
.multiselect-list-group .list-group-item.checkbox:has(input:focus-visible),
.multiselect-selectall-listgroup .list-group-item.checkbox:has(input:focus-visible) {
    background-color: var(--fb-tint-soft);
    box-shadow: inset 2px 0 0 var(--fb-link);
}

.multiselect-list-group .list-group-item.checkbox:has(input:focus-visible) input:focus-visible,
.multiselect-selectall-listgroup .list-group-item.checkbox:has(input:focus-visible) input:focus-visible {
    outline: none;
}

/* Same idea for the standalone Checkbox and Radio widgets: the label is the
   real hit target, so it carries the ring. */
.icsynergy-form .checkbox > label:has(input:focus-visible),
.icsynergy-form .radio > label:has(input:focus-visible) {
    outline: 2px solid var(--fb-link);
    outline-offset: 3px;
    border-radius: 3px;
}

.icsynergy-form .checkbox > label:has(input:focus-visible) input:focus-visible,
.icsynergy-form .radio > label:has(input:focus-visible) input:focus-visible {
    outline: none;
}

/* Subform collapse chevron - a round button, so a round ring. */
.icsynergy-form .subform-panel > .panel > .panel-heading > .panel-title > a[data-toggle="collapse"]:focus-visible {
    outline: 2px solid var(--fb-link);
    outline-offset: 2px;
    border-radius: 50%;
}

/* ── Section headings inside widget panels ──────────────────────────────── */

.icsynergy-form .user-search .panel-body > div > h4:not(.panel-title),
.icsynergy-form .custom-search .panel-body > div > h4:not(.panel-title) {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #4a5568;
    margin: 0 0 6px;
}

/* ── Heading widget (HD2 / HD3) ─────────────────────────────────────────────
   230 Heading widgets are authored across the asset configs and 220 of them
   take every default, so the defaults are what the forms actually look like.
   Both of the old problems came from the config layer, not from this file:

   - size is chosen per widget, and the six stock Bootstrap sizes span 36px to
     12px - a range no form panel can absorb. A size="1" section heading
     outweighed the panel title above it, and scale drifted between assets.
     Normalised below to a tight in-form scale that still reads as a hierarchy.
   - the section gap was an inline padding-top defaulting to 50px, which no
     stylesheet could reach. _heading.html now emits that inline style only when
     a config authored paddingTop (9 widgets do, all "0"), so the default is the
     token below and the density work applies to headings too.
   ─────────────────────────────────────────────────────────────────────────── */

.icsynergy-form .form-heading {
    padding-top: 18px;
    padding-bottom: 4px;
}

/* A heading that opens a panel sits directly under the panel header, so the
   section gap above it has already been spent. */
.icsynergy-form [data-icsynergy-form] > div:first-child .form-heading {
    padding-top: 0;
}

/* Colour and weight sit one step above .control-label (13px / 600 / --fb-ink):
   a section heading has to out-rank the labels it introduces, and at this
   density it has only a couple of pixels of size to do it with. */
.icsynergy-form .form-heading > h1,
.icsynergy-form .form-heading > h2,
.icsynergy-form .form-heading > h3,
.icsynergy-form .form-heading > h4,
.icsynergy-form .form-heading > h5,
.icsynergy-form .form-heading > h6 {
    margin: 0;
    color: var(--fb-navy);
    font-weight: 700;
    line-height: 1.3;
}

.icsynergy-form .form-heading > h1 { font-size: 20px; }
.icsynergy-form .form-heading > h2 { font-size: 18px; }
.icsynergy-form .form-heading > h3 { font-size: 16px; }

/* Sizes 4 and 5 are subsection headings, so they step back to label weight
   rather than competing with the size-3 heading above them. */
.icsynergy-form .form-heading > h4 { font-size: 14px; font-weight: 600; }
.icsynergy-form .form-heading > h5 { font-size: 13px; font-weight: 600; }

/* The smallest level lands on the micro-label treatment the search widgets
   already use for their in-panel section headings, rather than on 12px body
   text that would be indistinguishable from a field label. */
.icsynergy-form .form-heading > h6 {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--fb-ink-muted);
}

/* Subtext. Unscoped display:block - a description must never share the title's
   line, wherever a heading is rendered. */
.form-heading-subtext {
    display: block;
}

.icsynergy-form .form-heading > .form-heading-subtext {
    margin-top: 3px;
    font-size: 12px;
    line-height: 1.45;
    color: var(--fb-ink-muted);
}

/* linebreak="true" pairs the rule with the heading, so it should read as that
   heading's underline - tighter above than the freestanding .icsynergy-form hr
   separator, and no gap below beyond the wrapper's own padding. */
.icsynergy-form .form-heading > .form-line-break {
    margin-top: 6px;
    margin-bottom: 0;
}

/* ══ SUBFORMS ═══════════════════════════════════════════════════════════════
   The old design gave a subform exactly the same weight as the form
   containing it: a full panel with a grey heading, a shadow, and a solid red
   Remove button. A stack of them read as unrelated boxes with no hierarchy
   and no way to tell one instance from the next.

   Instead: a light card carrying a coloured accent rail on the left, a
   compact single-line header bar, a numbered chip for repeating instances,
   and a quiet Remove control that only turns red on hover. The rail colour
   carries the change state (added / modified / removed) that the panel
   context class used to signal by tinting the whole panel.
   ═════════════════════════════════════════════════════════════════════════ */

.subform-panel {
    margin-bottom: 8px;
}

/* No overflow:hidden here. It used to clip the panel's children to the rounded
   corners, but it also clipped anything that legitimately escapes the card -
   most visibly the datetimepicker dropdown of a DatePicker inside a subform,
   which is absolutely positioned inside .input-group.date and so was cut off at
   the panel edge. The corners are rounded on the children that would otherwise
   square them off instead (see the heading/body rules below). */
.icsynergy-form .subform-panel > .panel {
    border: 1px solid var(--fb-hairline);
    border-left: 3px solid var(--fb-rail);
    border-radius: 6px;
    box-shadow: none;
    background-color: #fff;
}

/* Inner radii: 5px against the 1px borders, 3px against the 3px left rail, so
   the fill follows the border curve exactly the way overflow:hidden did. */
.icsynergy-form .subform-panel > .panel > .panel-heading {
    padding: var(--fb-pad-y) var(--fb-pad-x);
    background-color: #fbfcfe;
    background-image: none;
    border-bottom: 1px solid var(--fb-hairline);
    border-top-left-radius: 3px;
    border-top-right-radius: 5px;
}

.icsynergy-form .subform-panel > .panel > .panel-body {
    background-color: #fff;
    padding: 9px 12px 1px;
    border-bottom-left-radius: 3px;
    border-bottom-right-radius: 5px;
}

/* Collapsed: the header bar is the whole card, so drop the seam. */
.icsynergy-form .subform-panel > .panel > .panel-body.collapse:not(.in) {
    border-top: 0;
}

.icsynergy-form .subform-panel > .panel > .panel-heading:not(:last-child):has(+ .collapse:not(.in)),
.icsynergy-form .subform-panel > .panel > .panel-heading:last-child {
    border-bottom: 0;
    border-bottom-left-radius: 3px;
    border-bottom-right-radius: 5px;
}

/* Header bar: one row, vertically centred, remove control pushed to the end.
   .panel-title keeps its tag and class - form.js resolves the remove spinner
   with .closest(".panel-title") - only its display changes. */
.icsynergy-form .subform-panel > .panel > .panel-heading > .panel-title {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 13px;
    font-weight: 600;
    color: var(--fb-ink);
    line-height: 1.35;
    margin: 0;
}

/* Collapse chevron as a quiet round button. */
.icsynergy-form .subform-panel > .panel > .panel-heading > .panel-title > a[data-toggle="collapse"] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    color: var(--fb-ink-muted);
    background-color: transparent;
    transition: background-color 0.12s, color 0.12s;
}

.icsynergy-form .subform-panel > .panel > .panel-heading > .panel-title > a[data-toggle="collapse"]:hover,
.icsynergy-form .subform-panel > .panel > .panel-heading > .panel-title > a[data-toggle="collapse"]:focus {
    background-color: #e6eef6;
    color: var(--fb-navy);
    text-decoration: none;
}

.icsynergy-form .subform-panel > .panel > .panel-heading > .panel-title > a[data-toggle="collapse"] .glyphicon {
    top: 0;
    font-size: 11px;
}

/* Change-state badges, restyled into the pill language used elsewhere. */
.icsynergy-form .subform-panel > .panel > .panel-heading .badge {
    background-color: #eef3f8;
    border: 1px solid var(--fb-border);
    border-radius: 999px;
    padding: 2px 9px;
    font-size: 11px;
    font-weight: 600;
    color: #4f6277;
}

.icsynergy-form .subform-panel > .panel > .panel-heading .badge .glyphicon {
    top: 1px;
    font-size: 10px;
    margin-right: 2px;
}

/* Remove: quiet until you mean it. */
.icsynergy-form .subform-panel .remove-form-btn {
    margin-left: auto;
    flex: 0 0 auto;
    padding: 3px 10px;
    font-size: 12px;
    font-weight: 600;
    background-color: #fff;
    background-image: none;
    border: 1px solid var(--fb-border);
    border-radius: 999px;
    color: #6a7b8d;
    text-shadow: none;
    box-shadow: none;
    transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}

.icsynergy-form .subform-panel .remove-form-btn:hover,
.icsynergy-form .subform-panel .remove-form-btn:focus {
    background-color: #fdf2f1;
    border-color: #e0a8a2;
    color: var(--fb-danger);
}

.icsynergy-form .subform-panel .remove-form-btn .glyphicon {
    top: 1px;
    font-size: 10px;
}

/* Change state moves onto the rail instead of tinting the whole panel. */
.icsynergy-form .subform-panel > .panel.panel-success  { border-left-color: #6cbf8b; }
.icsynergy-form .subform-panel > .panel.panel-info     { border-left-color: #5aa8c4; }
.icsynergy-form .subform-panel > .panel.panel-danger   { border-left-color: #d98b84; }
.icsynergy-form .subform-panel > .panel.panel-default  { border-left-color: var(--fb-rail); }

.icsynergy-form .subform-panel > .panel.panel-success > .panel-heading .badge {
    background-color: #e7f4ea;
    border-color: #bddfca;
    color: #256b3a;
}

.icsynergy-form .subform-panel > .panel.panel-info > .panel-heading .badge {
    background-color: #e6f3f8;
    border-color: #b6d9e6;
    color: #1c5d75;
}

.icsynergy-form .subform-panel > .panel.panel-danger > .panel-heading .badge {
    background-color: #fbe9e9;
    border-color: #efc4c4;
    color: #9f2f2f;
}

/* A removed subform's title is struck through rather than just recoloured.
   :first-of-type is the title span - the collapse chevron's glyphicons are
   nested inside the <a>, and the badge wrappers follow the title. */
.icsynergy-form .subform-panel > .panel.panel-danger > .panel-heading > .panel-title > span:first-of-type {
    text-decoration: line-through;
    color: #97a6b6;
}

/* Nested subforms step the fill down instead of nesting another full panel. */
.icsynergy-form .subform-panel .subform-panel > .panel {
    border-left-color: #dde5ee;
}

.icsynergy-form .subform-panel .subform-panel > .panel > .panel-heading {
    background-color: #f7f9fc;
}

/* The container the AJAX-added subforms are appended to. */
.icsynergy-subforms {
    position: relative;
}

/* ══ MULTISELECT ════════════════════════════════════════════════════════════ */

/* These sit on .panel-body's #fafafa, so a --fb-hairline edge disappeared into
   the background. The list pickers are the one widget family that needs to
   read as a contained control rather than as flowed content, so they get the
   stronger border, a white fill and a small lift. */
.icsynergy-form .multiselect-widget .panel,
.icsynergy-form .query-select-widget .panel {
    border: 1px solid var(--fb-border);
    border-radius: 6px;
    background-color: #fff;
    box-shadow: 0 1px 3px rgba(16, 42, 67, 0.07);
    overflow: hidden;
}

/* Same feedback as focusing an input, for the whole picker. */
.icsynergy-form .multiselect-widget .panel:focus-within,
.icsynergy-form .query-select-widget .panel:focus-within {
    border-color: #9db8d2;
    box-shadow: 0 1px 3px rgba(16, 42, 67, 0.07), 0 0 0 3px rgba(0, 44, 78, 0.10);
}

.icsynergy-form .multiselect-widget .panel-heading {
    padding: var(--fb-pad-y) var(--fb-pad-x);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: #4a5568;
    background-color: var(--fb-tint);
    background-image: none;
    border-bottom: 1px solid var(--fb-border);
}

.icsynergy-form .multiselect-widget .panel-body {
    background-color: #fff;
    padding: 7px var(--fb-pad-x);
    border-bottom: 1px solid var(--fb-border);
}

/* Selected chips ------------------------------------------------------------ */

.multiselect-selected {
    padding: 5px 6px 1px;
    background-color: #f4f7fa;
    border-bottom: 1px solid var(--fb-border);
    min-height: 30px;
    max-height: 84px;
}

.multiselect-selected .multiselect-label {
    /* .pull-left is applied by the backend (OptionsField.getClassForOption) and
       by buildMultiselectPill in form.js; inline-flex reads better and wraps
       the same way, so opt out of the float here rather than in either. */
    float: none !important;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
    margin: 0 4px 4px 0;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.35;
    text-align: left;
    white-space: normal;
    word-break: break-word;
}

.multiselect-selected .multiselect-label.label-primary {
    background-color: var(--fb-pill-bg);
    border: 1px solid var(--fb-pill-border);
    color: var(--fb-link);
}

.multiselect-selected .multiselect-label.label-default {
    background-color: #eef3f8;
    border: 1px solid var(--fb-border);
    color: #4f6277;
}

.multiselect-selected .multiselect-remove-btn {
    top: 0;
    flex: 0 0 auto;
    font-size: 9px;
    opacity: 0.55;
    transition: opacity 0.12s, color 0.12s;
}

.multiselect-selected .multiselect-label:hover .multiselect-remove-btn {
    opacity: 1;
}

.multiselect-selected .multiselect-remove-btn:hover {
    color: var(--fb-danger);
    opacity: 1;
}

.multiselect-none-selected {
    font-size: 12.5px;
    font-style: italic;
    color: #8a9bad;
}

/* Option list -------------------------------------------------------------- */

.multiselect-list-group,
.multiselect-selected-list-group,
.query-select-list-group {
    margin-bottom: 0;
    border-radius: 0;
}

/* No rules between option rows - the checkbox column, the hover fill and the
   checked marker give the list its structure. */
.multiselect-list-group .list-group-item.checkbox,
.multiselect-selectall-listgroup .list-group-item.checkbox {
    padding: 3px var(--fb-pad-x);
    margin: 0;
    border: 0;
    border-radius: 0;
    transition: background-color 0.1s;
}

.multiselect-list-group .list-group-item.checkbox:hover {
    background-color: var(--fb-tint-soft);
}

/* Checked rows get a marker so a long list is scannable without re-reading
   every checkbox. Enhancement only - browsers without :has() just skip it. */
.multiselect-list-group .list-group-item.checkbox:has(input:checked) {
    background-color: #f0f7fd;
    box-shadow: inset 2px 0 0 var(--fb-navy);
}

.multiselect-list-group .list-group-item.checkbox.disabled {
    background-color: #fafbfc;
    color: #6b7c8f;
}

.multiselect-checkbox-label {
    display: block;
    margin: 0;
    padding-left: 19px;
    font-size: 13px;
    font-weight: 400;
    line-height: 1.5;
    color: #33475b;
}

.multiselect-checkbox-label > .multiselect-checkbox {
    margin-left: -20px;
    margin-top: 3px;
}

/* Divider options render as a bare span with no label - present them as the
   section headers they are. */
.multiselect-list-group .list-group-item.checkbox:not(:has(label)) {
    background-color: #f4f7fa;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #64748b;
}

.multiselect-selectall-listgroup .list-group-item.checkbox {
    background-color: #fbfcfe;
    font-weight: 600;
}

/* Current-selections panel ------------------------------------------------- */

.multiselect-selected-list-group .list-group-item,
.query-select-list-group .list-group-item {
    padding: 3px var(--fb-pad-x);
    border: 0;
    border-radius: 0;
    font-size: 13px;
    color: #33475b;
}

/* QuerySelect keeps row rules: its lists are add/remove ledgers, where the
   delineation carries meaning rather than just decorating. The multiselect's
   Current Selections list matches its own option list and has none. */
.query-select-list-group .list-group-item {
    border-bottom: 1px solid var(--fb-hairline);
}

.query-select-list-group .list-group-item:last-child {
    border-bottom: 0;
}

.multiselect-selected-list-group .list-group-item:hover,
.query-select-list-group .list-group-item:hover {
    background-color: var(--fb-tint-soft);
}

.multiselect-selected-list-remove-icon,
.query-select-remove-icon {
    font-size: 10px;
    color: #9aabbd;
    transition: color 0.12s;
}

.multiselect-selected-list-remove-link:hover .multiselect-selected-list-remove-icon,
.query-select-add-remove-link:hover .query-select-remove-icon,
.query-select-remove-remove-link:hover .query-select-remove-icon {
    color: var(--fb-danger);
}

/* Count badges in the widget panel headers. */
.icsynergy-form .multiselect-widget .panel-heading .label-primary,
.icsynergy-form .query-select-widget .panel-heading .label-primary {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    background-color: #dfe9f3;
    color: var(--fb-link);
    font-size: 11px;
    font-weight: 700;
}

/* The message line under the server-search box. Three kinds of message share it -
   the help hint, "no matches", and errors - so the default tone here is the quiet
   one (the same muted 12.5px as .certify-action-hint, the other "what to do next"
   line in the product) and only a real failure gets the error class from
   setMultiSelectSearchMessage.

   It carried inline "padding-top:5px;color:red" with the hint wrapped in a black
   <i> to escape the red. That made the hint italic, which reads as emphasis on a
   line that is the least emphatic thing in the widget, and left the default tone
   for every message as an error. */
.multiselect-search-message,
.multiselect-search-message .multiselect-search-help {
    display: flex;
    align-items: baseline;
    gap: 6px;
}

.multiselect-search-message {
    padding-top: 6px;
    /* Deliberately darker than --fb-ink-muted, which is 3.58:1 on white and so
       fails AA at this size. This is 5.39:1 - close enough to the error tone's
       5.44:1 that the two messages read as equally legible, differing in colour
       only because one is a failure. */
    color: #4f6d8c;
    font-size: 12.5px;
    line-height: 1.45;
}

/* Cleared after a search that returned rows - drop the padding too, so the option
   list moves up flush against the search box rather than sitting on dead space. */
.multiselect-search-message:empty {
    display: none;
}

/* Bootstrap glyphicons carry their own line-height and sit a shade high next to
   text on a baseline row. */
.multiselect-search-message > .glyphicon,
.multiselect-search-message .multiselect-search-help > .glyphicon {
    flex: 0 0 auto;
    top: 1px;
    font-size: 11px;
}

.multiselect-search-message.multiselect-search-message-error {
    color: var(--fb-danger);
}

/* Filter match count (MS1) and Select All count (MS2) ----------------------- */

/* Both reuse the pill shape of the panel-header count badges above so the three
   counts in one widget read as the same kind of thing. .label-default rather
   than .label-primary because these are secondary to the header count - and
   because .label-default is what the templates carry, matched on .label so
   custom-style.css's later .label-default rule cannot win. */
.icsynergy-form .multiselect-widget .label.multiselect-filter-count,
.icsynergy-form .multiselect-widget .label.multiselect-selectall-count {
    display: inline-block;
    padding: 2px 7px;
    border-radius: 999px;
    background-color: var(--fb-tint);
    color: var(--fb-ink-muted);
    font-size: 11px;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}

/* The filter box and its badge sit on one line, badge hugging the right edge so
   it does not shift as the digit count changes. */
.icsynergy-form .multiselect-widget .multiselect-filter {
    display: flex;
    align-items: center;
    gap: 8px;
}

.icsynergy-form .multiselect-widget .multiselect-filter > .multiselect-search {
    flex: 1 1 auto;
}

.icsynergy-form .multiselect-widget .label.multiselect-filter-count {
    flex: 0 0 auto;
}

/* Kept inline rather than pushed right with flex: .multiselect-checkbox-label is
   display:block with padding-left:19px and the checkbox pulled back by -20px, and
   turning it into a flex container breaks that negative-margin alignment. */
.icsynergy-form .multiselect-widget .label.multiselect-selectall-count {
    margin-left: 8px;
    vertical-align: baseline;
}

/* An empty count would collapse to a bare pill; the .hidden class the JS toggles
   is what actually removes it, this is belt-and-braces for the initial render. */
.icsynergy-form .multiselect-widget .label.multiselect-selectall-count:empty {
    display: none;
}

/* Server search bar (MS3) --------------------------------------------------
   The criteria box and its Search button are a Bootstrap .input-group in the
   template, so the joined corners and the matching control height both come
   from rules that already exist: ".input-group .form-control:first-child"
   squares the input's inner edge, and the shared
   ".icsynergy-form input.form-control, .icsynergy-form .input-group-btn > .btn"
   rule pins both halves to --fb-control-h. Nothing here restates either - the
   button stays the same height as every other control in the form.

   This row only has to place the spinner beside the joined control. It is a
   sibling of the group rather than a second member of .input-group-btn (which
   is how the user search does it) so that revealing it mid-search cannot widen
   the group and squeeze the input. */
.icsynergy-form .multiselect-widget .multiselect-search-bar {
    display: flex;
    align-items: center;
    gap: 8px;
}

.icsynergy-form .multiselect-widget .multiselect-search-group {
    /* min-width:0 so a long placeholder cannot push the group past the panel. */
    flex: 1 1 auto;
    min-width: 0;
}

.icsynergy-form .multiselect-widget .multiselect-search-spinner {
    flex: 0 0 auto;
    line-height: 0;
}

/* Sits directly under the (now empty) option list, inside the picker's border. */
.multiselect-no-matches {
    padding: 10px 12px;
    border-top: 1px solid var(--fb-hairline);
    background-color: #fff;
    color: var(--fb-ink-muted);
    font-size: 12.5px;
    line-height: 1.45;
}

/* ══ QUERY SELECT ═══════════════════════════════════════════════════════════ */


.icsynergy-form .query-select-widget .panel-heading {
    padding: var(--fb-pad-y) var(--fb-pad-x);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: #4a5568;
    background-color: var(--fb-tint);
    background-image: none;
    border-bottom: 1px solid var(--fb-border);
}

.icsynergy-form .query-select-widget .panel-body {
    background-color: #fff;
    padding: 7px var(--fb-pad-x);
    border-bottom: 1px solid var(--fb-border);
}

.query-select-error {
    font-size: 12.5px;
    padding-left: 15px;
}

/* ══ MULTITEXT ══════════════════════════════════════════════════════════════ */

.multitext-single {
    padding-top: 1px;
    padding-bottom: 1px;
}

/* The +/- controls were full-weight primary and danger buttons, one pair per
   row, which drowned out the actual inputs.

   Selectors no longer say ".multitext-single .btn.multitext-add": after MT1 the
   Add button sits in .multitext-actions, outside the rows, so that rule had
   stopped matching it. Scoped to .multitext-widget instead, which covers both. */
.icsynergy-form .multitext-widget .btn.multitext-add,
.icsynergy-form .multitext-widget .btn.multitext-remove {
    background-color: #fff;
    background-image: none;
    border-color: var(--fb-border);
    color: #6a7b8d;
    text-shadow: none;
    box-shadow: none;
    transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}

.icsynergy-form .multitext-widget .btn.multitext-add:hover,
.icsynergy-form .multitext-widget .btn.multitext-add:focus {
    background-color: #edf4fa;
    border-color: #a9c3da;
    color: var(--fb-navy);
}

.icsynergy-form .multitext-widget .btn.multitext-remove:not([disabled]):hover,
.icsynergy-form .multitext-widget .btn.multitext-remove:not([disabled]):focus {
    background-color: #fdf2f1;
    border-color: #e0a8a2;
    color: var(--fb-danger);
}

.multitext-parsley-container:empty {
    display: none;
}

/* MT1: the single Add, below the scroll container. Deliberately wider and labelled
   rather than the old bare "+" - it is now the one control that grows the field, so
   it should say so. Sized down from a default .btn so it reads as secondary to the
   inputs above it. */
.icsynergy-form .multitext-actions {
    margin-top: 6px;
}

.icsynergy-form .multitext-widget .btn.multitext-add {
    padding: 3px 12px;
    border-radius: 999px;
    font-size: 12.5px;
    font-weight: 600;
}

.icsynergy-form .multitext-widget .btn.multitext-add .glyphicon {
    top: 1px;
    margin-right: 4px;
    font-size: 10px;
}

/* Remove keeps the row's square right edge (it is an input-group member), so only
   the Add button gets the pill shape. */
.icsynergy-form .multitext-widget .btn.multitext-remove .glyphicon {
    top: 1px;
    font-size: 10px;
}

/* Disabled = this is the last row and removing it would leave nothing to type in.
   Muted rather than hidden so the row's width does not jump as rows come and go. */
.icsynergy-form .multitext-widget .btn.multitext-remove[disabled] {
    background-color: #fafbfc;
    border-color: var(--fb-hairline);
    color: #b6c2cf;
    opacity: 1;
    cursor: not-allowed;
}

/* ══ USER SEARCH / CUSTOM SEARCH ════════════════════════════════════════════
   .user-search lives in icrare2 (templates/search/_user_search_widget.html)
   and .custom-search in icamp-app, but they are the same shape - a panel with
   a basic/advanced search toggle and a results panel - so they share
   treatment here.
   ═════════════════════════════════════════════════════════════════════════ */

.icsynergy-form .user-search.panel,
.icsynergy-form .custom-search.panel {
    border: 1px solid var(--fb-hairline);
    border-radius: 6px;
    box-shadow: none;
}

/* Flex row so the SR2 mode switch can sit right-aligned against the title, the
   same grammar as .ics-panel-heading. flex-wrap means that at narrow widths the
   switch drops onto its own line under the title rather than squeezing it. */
.icsynergy-form .user-search > .panel-heading,
.icsynergy-form .custom-search > .panel-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 6px 12px;
    padding: 6px 12px;
    background-color: var(--fb-tint);
    background-image: none;
    border-bottom: 1px solid var(--fb-hairline);
    border-radius: 6px 6px 0 0;
}

.icsynergy-form .user-search > .panel-heading > .panel-title,
.icsynergy-form .custom-search > .panel-heading > .panel-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--fb-ink);
    margin: 0;
    /* The flexible half of the heading flex row - the mode switch keeps its
       labels intact and the title is what gives way. */
    flex: 1 1 auto;
}

.icsynergy-form .user-search > .panel-body,
.icsynergy-form .custom-search > .panel-body {
    background-color: #fff;
    padding: 10px 12px;
}

.user-search .panel-body > p,
.custom-search .panel-body > p,
.user-search-basic > p,
.custom-search .panel-body p {
    font-size: 12.5px;
    color: var(--fb-ink-muted);
}

/* G6. Both widget fragments used to space themselves with markup: a bare <br/>
   as the fragment's first node, a <br/> before each search-mode toggle, and
   <p/><p/> as a gap. Those are gone from the templates; the spacing they were
   standing in for is declared here instead.

   The <p/><p/> pair mattered beyond tidiness - a self-closed <p> is not valid
   HTML, so the parser treated each as an OPENING tag and the "gap" silently
   became a paragraph wrapping the button that followed it. */

.icsynergy-form .user-search.panel,
.icsynergy-form .custom-search.panel,
.user-search-selected-user,
.custom-search-selected-object {
    margin-top: 10px;
}

/* SR2: the two mode buttons are now a segmented switch sitting above both search
   panels instead of a lone btn-link inside each. The G6 margin rules that used to
   live here (replacing the <br/> and <p/><p/> those links carried) are gone with
   them - spacing belongs to the group now. */
/* Lives in the panel heading, which is a flex row - so no margins of its own, and
   flex-shrink off so the segments keep their labels intact and the title is what
   gives way.

   Deliberately does NOT override display: .btn-group is inline-block with floated
   children in Bootstrap 3, and switching it to flex changes how the segment
   border-radius and the -1px seam between buttons resolve. */
/* .user-admin-page shares these rather than copying them: the search tool's
   basic/advanced toggle is the same control as the widget's, and it sits in an
   .ics-panel-heading, which is a flex row for the same reason the widget's
   heading is. */
.icsynergy-form .search-mode-switch,
.user-admin-page .search-mode-switch {
    flex: 0 0 auto;
    margin: 0;
}

/* Config-injected additionalText was followed by a <br/>. The template now
   tags that wrapper so it can be spaced from here. */
.icsynergy-form .search-additional-text {
    margin-bottom: 6px;
}

/* Results containers carried a lone <p/> above them as a gap. Both keep their
   id for the JS to target; these classes exist only to space them. */
.icsynergy-form .user-search-results,
.icsynergy-form .custom-search-results {
    margin-top: 10px;
}

/* G5. Empty grid columns used purely to indent or force a line break. Below the
   sm breakpoint a col-sm-* is a full-width block, so the alignment they provide
   is gone and only their content contributes height - which for the two that
   hold an &nbsp; is a stray blank line.

   Removing them outright would change desktop alignment, so they are neutered
   at mobile widths only.

   Matched as div.col-sm-2 rather than .col-sm-2:first-child on purpose: the
   per-attribute rows of the advanced search form open with a real
   <label class="col-sm-2 control-label">, and hiding those at mobile is the
   label-disappearing bug, not a fix. A label is not a div, so it cannot match. */
@media (max-width: 767px) {
    .icsynergy-form .grid-spacer,
    .user-admin-page .grid-spacer {
        display: none;
    }
}

/* Selected user / selected object summary bar. */
.user-search-selected-user,
.custom-search-selected-object > div > .widget-wrapper {
    padding: 7px 12px;
    margin-bottom: 7px;
    background-color: var(--fb-tint);
    border: 1px solid var(--fb-hairline);
    border-radius: 6px;
    font-size: 13px;
    color: #33475b;
}

/* SR6: selected-user bar rebuilt as a header plus one flex row per user.

   Replaces ".user-search-selected-user b" (weight came from the tag) and the two
   ".dl-horizontal" rules (spacing on a definition list being used for layout).
   Single-user and multi-user modes now render as the same component - one row or
   several - instead of two unrelated layouts. */

.user-search-selected-user .selected-user-header {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 6px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--fb-ink-muted);
}

.user-search-selected-user .selected-user-header-icon {
    font-size: 11px;
    color: #7d9ab5;
}

/* One row per selected user: chip left, action pushed right. No fixed column
   width, so a long name no longer collides with the button - it wraps and the
   action stays on the row's trailing edge. */
.user-search-selected-user .selected-user-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 10px;
    padding: 3px 0;
}

/* ":not(.hidden) ~ :not(.hidden)", not "+". The clone-source placeholder row is a
   .hidden sibling that sits BETWEEN the server-rendered rows and the JS-appended
   clones (user_search.js appends to the same container, after the placeholder).
   With "+", a form that starts with no selected users would give its first cloned
   row a top border, because the row immediately before it is the placeholder. The
   general sibling form asks "is there any VISIBLE row before me", which is the
   actual question. Clones are un-hidden by the clone, so they participate. */
.user-search-selected-user .selected-user-row:not(.hidden) ~ .selected-user-row:not(.hidden) {
    border-top: 1px solid var(--fb-hairline);
}

/* margin-left:auto rather than a display declaration on purpose: jQuery .hide()
   / .show() toggle this span for the single-user "Change Selected User" control
   (user_search.js ~235 and ~503), and .show() restores display to "" - so it must
   be able to fall back to its natural inline value. */
.user-search-selected-user .selected-user-row-actions {
    margin-left: auto;
}

/* Row action buttons. These were stock .btn-xs .btn-default - grey gradient boxes
   with 1px/5px padding, which read as heavier than the chip they sit beside while
   being a smaller click target than the chip.

   Deliberately the SAME pattern as .subform-panel .remove-form-btn: white pill,
   muted label, and destructive intent shown only on hover/focus. "Remove this
   user" and "remove this subform" are the same kind of act, so they should not
   look like two different controls. Qualified with .btn so it outranks
   custom-style.css's later .btn-default gradient. */
.icsynergy-form .user-search-selected-user .selected-user-row-actions > .btn {
    padding: 2px 11px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.5;
    background-color: #fff;
    background-image: none;
    border: 1px solid var(--fb-border);
    border-radius: 999px;
    color: #6a7b8d;
    text-shadow: none;
    box-shadow: none;
    transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}

/* Remove: quiet until you mean it. */
.icsynergy-form .user-search-selected-user .selected-user-row-actions > .btn.user-search-remove-user-btn:hover,
.icsynergy-form .user-search-selected-user .selected-user-row-actions > .btn.user-search-remove-user-btn:focus {
    background-color: #fdf2f1;
    border-color: #e0a8a2;
    color: var(--fb-danger);
}

/* Change Selected User is not destructive, so it hovers neutral-navy instead.
   This also settles SR4: it was .btn-xs at 1px/5px padding, a genuinely small
   target for a fairly consequential action. */
.icsynergy-form .user-search-selected-user .selected-user-row-actions > .btn.user-search-change-selected-user-btn:hover,
.icsynergy-form .user-search-selected-user .selected-user-row-actions > .btn.user-search-change-selected-user-btn:focus {
    background-color: var(--fb-tint);
    border-color: #c3d2e0;
    color: var(--fb-navy);
}

.icsynergy-form .user-search-selected-user .selected-user-row-actions > .btn .glyphicon {
    top: 1px;
    margin-right: 3px;
    font-size: 10px;
}

/* The user popover chip. Scoped to the form pages, and matching on .label as
   well so it outranks custom-style.css's later ".label-primary" /
   ".label-info" background overrides - without the extra class the fill stays
   solid #28587d and the text below is unreadable on it. */
#form-contents .label.user-expansion-label-popover,
.icsynergy-form .label.user-expansion-label-popover,
.audit-viewer-page .label.user-expansion-label-popover {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    background-color: var(--fb-pill-bg);
    border: 1px solid var(--fb-pill-border);
    color: var(--fb-link);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.12s, border-color 0.12s;
}

#form-contents .label.user-expansion-label-popover:hover,
.icsynergy-form .label.user-expansion-label-popover:hover,
.audit-viewer-page .label.user-expansion-label-popover:hover,
#form-contents .label.user-expansion-label-popover:focus,
.icsynergy-form .label.user-expansion-label-popover:focus,
.audit-viewer-page .label.user-expansion-label-popover:focus {
    background-color: #d9eaf7;
    border-color: #a9c9e3;
    color: var(--fb-navy);
}

/* The same chip inside an alert. ".alert a" below sets the link ink and beats
   Bootstrap's white ".label" colour, which left the name at #0a4e78 on the
   #28587d ".label-primary" fill - about 1.4:1, effectively invisible. Match on
   ".alert" plus ".label" so this outranks both. Covers -primary, -default and
   -info, since the tone class is not part of the selector. */
.alert .label.user-expansion-label-popover {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    background-color: var(--fb-pill-bg);
    border: 1px solid var(--fb-pill-border);
    color: var(--fb-link);
    font-size: 12px;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.12s, border-color 0.12s;
}

.alert .label.user-expansion-label-popover:hover,
.alert .label.user-expansion-label-popover:focus {
    background-color: #d9eaf7;
    border-color: #a9c9e3;
    color: var(--fb-navy);
    text-decoration: none;
}

/* Search submit buttons across every search widget, unified as the primary
   action they are. */
.icsynergy-form .btn.multiselect-search-button,
.user-admin-page .btn.search-tool-basic-btn,
.user-admin-page .btn.search-tool-advanced-btn,
.icsynergy-form .btn.search-basic-btn,
.icsynergy-form .btn.search-advanced-btn,
.icsynergy-form .btn.custom-search-basic-btn,
.icsynergy-form .btn.custom-search-advanced-btn,
.icsynergy-form .btn.query-select-add-search-btn,
.icsynergy-form .btn.query-select-remove-search-btn {
    background-color: var(--fb-navy);
    background-image: none;
    border-color: var(--fb-navy);
    color: #fff;
    font-weight: 600;
    text-shadow: none;
    box-shadow: none;
    transition: background-color 0.12s, border-color 0.12s;
}

.icsynergy-form .btn.multiselect-search-button:hover,
.user-admin-page .btn.search-tool-basic-btn:hover,
.user-admin-page .btn.search-tool-advanced-btn:hover,
.user-admin-page .btn.search-tool-basic-btn:focus,
.user-admin-page .btn.search-tool-advanced-btn:focus,
.icsynergy-form .btn.search-basic-btn:hover,
.icsynergy-form .btn.search-advanced-btn:hover,
.icsynergy-form .btn.custom-search-basic-btn:hover,
.icsynergy-form .btn.custom-search-advanced-btn:hover,
.icsynergy-form .btn.query-select-add-search-btn:hover,
.icsynergy-form .btn.query-select-remove-search-btn:hover,
.icsynergy-form .btn.multiselect-search-button:focus,
.icsynergy-form .btn.search-basic-btn:focus,
.icsynergy-form .btn.search-advanced-btn:focus,
.icsynergy-form .btn.custom-search-basic-btn:focus,
.icsynergy-form .btn.custom-search-advanced-btn:focus,
.icsynergy-form .btn.query-select-add-search-btn:focus,
.icsynergy-form .btn.query-select-remove-search-btn:focus {
    background-color: #013e6c;
    border-color: #013e6c;
    color: #fff;
}

/* SR2: segmented basic/advanced switch.

   These four buttons used to carry .btn-link without .btn and were styled here as
   text links. They are now real .btn.btn-default members of a .btn-group, and the
   current mode is carried by aria-pressed - which is both the accessible state for
   a toggle button and the thing this styles, so there is no separate class that
   could disagree with what a screen reader is told.

   Qualified with .btn so it outranks custom-style.css's later .btn-default
   gradient, the same reason .page-header-buttons .btn is written that way. */
/* Slimmer than a normal btn-sm: it shares a 6px-padded panel heading with 13px
   title text, so a full-height button would drive the header taller than the
   title needs. */
.icsynergy-form .search-mode-switch > .btn.btn-default,
.user-admin-page .search-mode-switch > .btn.btn-default {
    padding: 2px 11px;
    background-color: #fff;
    background-image: none;
    border-color: var(--fb-border);
    color: var(--fb-ink-muted);
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.5;
    text-shadow: none;
    box-shadow: none;
}

/* Selected segment: the light selected-chip tokens rather than filled navy. Solid
   navy read as far too heavy for a mode toggle sitting under a search field - it
   drew more attention than the search itself. These are the same two tokens the
   MultiSelect uses for a selected chip, so "selected" looks the same across the
   form. Contrast against the unselected white segment comes from the tint plus
   the darker, heavier label, not from a strong fill. */
.icsynergy-form .search-mode-switch > .btn.btn-default[aria-pressed="true"],
.user-admin-page .search-mode-switch > .btn.btn-default[aria-pressed="true"] {
    background-color: var(--fb-pill-bg);
    border-color: var(--fb-pill-border);
    color: var(--fb-navy);
}

.icsynergy-form .search-mode-switch > .btn.btn-default[aria-pressed="false"]:hover,
.icsynergy-form .search-mode-switch > .btn.btn-default[aria-pressed="false"]:focus,
.user-admin-page .search-mode-switch > .btn.btn-default[aria-pressed="false"]:hover,
.user-admin-page .search-mode-switch > .btn.btn-default[aria-pressed="false"]:focus {
    background-color: var(--fb-tint);
    border-color: #c3d2e0;
    color: var(--fb-ink);
}

/* SR1: results are a flat section now, not a third nested panel.

   The three rules that used to be here styled
   ".icsynergy-form .user-search-search-results-panel.panel" and
   ".icsynergy-form .custom-search .panel-body .panel-default" - both of which were
   the results panels and nothing else, so they went with the panels. Note the
   unscoped ".user-search-search-results-panel" box-shadow further up is NOT dead:
   custom-ahs search_user_tool.html still uses that class on a real panel, and it
   is not inside .icsynergy-form, so these scoped rules never reached it.

   Typography is carried over deliberately - same size, weight, casing and colour
   as the old panel-title - so only the box disappears, not the visual language. */
.icsynergy-form .user-search-results,
.icsynergy-form .custom-search-results {
    padding-top: 10px;
    border-top: 1px solid var(--fb-hairline);
}

.icsynergy-form .search-results-title {
    margin: 0 0 8px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: #4a5568;
}

/* The results fragment opens with .table-responsive; with the panel gone there is
   no panel-body padding to sit inside, so the table owns its own edges. */
.icsynergy-form .user-search-results .table,
.icsynergy-form .custom-search-results .table {
    margin-bottom: 0;
}

.icsynergy-form .user-search-results .alert,
.icsynergy-form .custom-search-results .alert {
    margin-bottom: 8px;
}

/* ── Advanced-search operand dropdown ──────────────────────────────────────
   The Equals / Starts with / Contains control at the head of each advanced
   search row. It is a modifier on the field beside it, not an action, so it has
   to stay quieter than the value input while still reading as operable.

   .user-search-tool-advanced-form is custom-ahs's search tool. Its markup is the
   same shape as the other two, but its class name differs by one word, so it
   never matched this rule and kept the stock grey gradient - which put more
   weight on the operator than on what was being searched for. */
.user-search-advanced-form .input-group-btn > .btn.dropdown-toggle,
.custom-search-advanced-form .input-group-btn > .btn.dropdown-toggle,
.user-search-tool-advanced-form .input-group-btn > .btn.dropdown-toggle {
    background-color: var(--fb-tint);
    background-image: none;
    border-color: var(--fb-border);
    color: #4f6277;
    font-size: 12.5px;
    /* Semibold because the button is showing a chosen value, not a label - it is
       the answer to "how should this field match?" and should read like one. */
    font-weight: 600;
    text-shadow: none;
    box-shadow: none;
    /* "Starts with" is two words and wrapped inside the button at narrow widths,
       which pushed the row taller than the input beside it. */
    white-space: nowrap;
    transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}

.user-search-advanced-form .input-group-btn > .btn.dropdown-toggle:hover,
.custom-search-advanced-form .input-group-btn > .btn.dropdown-toggle:hover,
.user-search-tool-advanced-form .input-group-btn > .btn.dropdown-toggle:hover,
.user-search-advanced-form .input-group-btn > .btn.dropdown-toggle:focus,
.custom-search-advanced-form .input-group-btn > .btn.dropdown-toggle:focus,
.user-search-tool-advanced-form .input-group-btn > .btn.dropdown-toggle:focus {
    background-color: #e7eef6;
    border-color: var(--fb-rail);
    color: var(--fb-navy);
}

/* Open state keyed on aria-expanded rather than Bootstrap's .open class: it is
   the accessible state the trigger already publishes, so the styling cannot
   disagree with what a screen reader is told - the same reasoning as
   aria-pressed on the basic/advanced mode switch. */
.user-search-advanced-form .input-group-btn > .btn.dropdown-toggle[aria-expanded="true"],
.custom-search-advanced-form .input-group-btn > .btn.dropdown-toggle[aria-expanded="true"],
.user-search-tool-advanced-form .input-group-btn > .btn.dropdown-toggle[aria-expanded="true"] {
    background-color: var(--fb-pill-bg);
    border-color: var(--fb-pill-border);
    color: var(--fb-navy);
}

/* The caret is punctuation, not content - it should not compete with the word. */
.user-search-advanced-form .input-group-btn > .btn.dropdown-toggle > .caret,
.custom-search-advanced-form .input-group-btn > .btn.dropdown-toggle > .caret,
.user-search-tool-advanced-form .input-group-btn > .btn.dropdown-toggle > .caret {
    margin-left: 6px;
    color: #8ba3ba;
}

/* Menu. Stock Bootstrap 3 renders these at 14px with generous padding, so a
   three-item operator list opened as a box taller than the row it belonged to. */
.user-search-advanced-form .dropdown-menu > li > a,
.custom-search-advanced-form .dropdown-menu > li > a,
.user-search-tool-advanced-form .dropdown-menu > li > a {
    padding: 5px 14px;
    font-size: 12.5px;
    color: #4f6277;
}

.user-search-advanced-form .dropdown-menu > li > a:hover,
.custom-search-advanced-form .dropdown-menu > li > a:hover,
.user-search-tool-advanced-form .dropdown-menu > li > a:hover,
.user-search-advanced-form .dropdown-menu > li > a:focus,
.custom-search-advanced-form .dropdown-menu > li > a:focus,
.user-search-tool-advanced-form .dropdown-menu > li > a:focus {
    background-color: var(--fb-tint);
    background-image: none;
    color: var(--fb-navy);
}

/* ── UserSearch basic "Find a User" field ────────────────────────────────
   Both of Bootstrap's input-group seam rules land wrong on this markup, which
   left the group's corners inverted - rounded where the input meets the button,
   square on the outside:

   - ".input-group .form-control:first-child", which squares the input's inner
     corners, does NOT match: the sr-only <label> is the group's first child, so
     the input kept its full 4px including the edge against the button.
   - ".input-group-btn:last-child > .btn:not(:last-child)" DOES match, because
     the spinner <span> follows the button - so Bootstrap squared the button's
     OUTER corners rather than the seam.

   Both are therefore set explicitly rather than left to Bootstrap. The button
   selector is deliberately more specific than that :not() rule (which counts
   0,5,0) so this does not rest on stylesheet order.

   Height is a local custom property so the input and its button cannot drift
   apart; the shared --fb-control-h stays 30px for every other control. */
.icsynergy-form .findUserInput {
    --search-control-h: 34px;
    --search-control-radius: 6px;
}

.icsynergy-form .findUserInput > .search-input-basic.form-control {
    height: var(--search-control-h);
    padding: 4px 12px;
    font-size: 13.5px;
    border-radius: var(--search-control-radius) 0 0 var(--search-control-radius);
}

.icsynergy-form .findUserInput > .input-group-btn:last-child > .btn.search-basic-btn {
    height: var(--search-control-h);
    padding-right: 16px;
    padding-left: 16px;
    border-radius: 0 var(--search-control-radius) var(--search-control-radius) 0;
}

/* user_search.js flags a too-short search by adding .has-error to the INPUT,
   but every Bootstrap 3 .has-error rule expects the class on an ancestor
   (".has-error .form-control"), so it matched nothing and clicking Search with
   under two characters gave no feedback at all. The :hover selector is present
   to outrank ".form-control:hover:not([disabled])" above, which would otherwise
   pull the border back to grey on hover. */
.icsynergy-form .form-control.has-error,
.icsynergy-form .form-control.has-error:hover:not([disabled]) {
    border-color: #a94442;
}

.icsynergy-form .form-control.has-error:focus {
    border-color: #843534;
    box-shadow: 0 0 0 3px rgba(169, 68, 66, 0.15);
}

/* ── Scrollbars in the widget lists ─────────────────────────────────────── */

.multiselect-list-group::-webkit-scrollbar,
.multiselect-selected-list-group::-webkit-scrollbar,
.multiselect-selected::-webkit-scrollbar,
.query-select-list-group::-webkit-scrollbar {
    -webkit-appearance: none;
    width: 8px;
}

.multiselect-list-group::-webkit-scrollbar-thumb,
.multiselect-selected-list-group::-webkit-scrollbar-thumb,
.multiselect-selected::-webkit-scrollbar-thumb,
.query-select-list-group::-webkit-scrollbar-thumb {
    border-radius: 4px;
    background-color: rgba(26, 58, 92, 0.28);
    -webkit-box-shadow: none;
    box-shadow: none;
}

.multiselect-list-group:hover::-webkit-scrollbar-thumb,
.multiselect-selected-list-group:hover::-webkit-scrollbar-thumb,
.multiselect-selected:hover::-webkit-scrollbar-thumb,
.query-select-list-group:hover::-webkit-scrollbar-thumb {
    background-color: rgba(26, 58, 92, 0.45);
}

/* ── Reclaiming vertical space ───────────────────────────────────────────
   Stock Bootstrap 3 spacing assumes a tall viewport. These are the remaining
   places the form builder spends height on nothing.
   ─────────────────────────────────────────────────────────────────────── */

/* Both search widget fragments open with a bare <br/> before their first
   panel. custom-style.css already suppresses this for #search-existing; the
   same waste applies everywhere they are used. */
.icsynergy-form .form-html-padding > br:first-child,
.icsynergy-form .widget-wrapper > br:first-child {
    display: none;
}

/* Html widgets are the usual carrier for notices; .alert costs 15px of padding
   and 20px of bottom margin at stock size.

   The left padding keeps the tone glyph gutter that the PAGE-LEVEL ALERTS block
   at the end of this file reserves, just tighter - drop it back to 12px and the
   notice text prints over the glyph. */
.icsynergy-form .alert {
    padding: 8px 12px 8px 33px;
    margin-bottom: 8px;
    background-position: 11px 9px;
    background-size: 14px 14px;
    font-size: 13px;
    line-height: 1.45;
    border-radius: 6px;
}

.icsynergy-form .alert h4 {
    font-size: 13px;
    margin: 0 0 3px;
}

.icsynergy-form .alert p:last-child {
    margin-bottom: 0;
}

.icsynergy-form .form-html-padding > p,
.icsynergy-form .form-html-padding > div > p {
    margin-bottom: 6px;
}

/* Heading widget h1-h6 margins are handled with the rest of the heading scale
   in the "Heading widget (HD2 / HD3)" block above. The rule that lived here
   keyed off .form-html-padding, which the Html widget shares, so it also
   retuned headings inside injected markup - those are now the Html widget's
   own concern (HT1), not the Heading widget's. */
.icsynergy-form .form-html-padding:not(.form-heading) > h1,
.icsynergy-form .form-html-padding:not(.form-heading) > h2,
.icsynergy-form .form-html-padding:not(.form-heading) > h3,
.icsynergy-form .form-html-padding:not(.form-heading) > h4,
.icsynergy-form .form-html-padding:not(.form-heading) > h5,
.icsynergy-form .form-html-padding:not(.form-heading) > h6 {
    margin-top: 4px;
    margin-bottom: 4px;
}

/* ── Html widget separators ─────────────────────────────────────────────
   22 Form configs across 16 assets author their section dividers as
       <Html name="separator" text="<hr style='border:1px solid #284F98;'/>">
   That shorthand borders all four sides of a zero-height element, so it
   renders as a heavy ~2px navy bar - the reason it reads as shouty rather
   than as a divider. Reset to a single hairline top border.

   This is done here rather than in the 22 configs because: inline styles can
   only be beaten by !important either way; one rule also covers the live DB
   config, which may have drifted from the files in deployment/config; and it
   covers separators authored the same way in future. If the intent is to
   change the authored markup instead, the files are
   custom-ahs/deployment/config/icrare2/assets/*_config.xml.

   Out of scope deliberately: the two email templates under
   config/notification (CSS cannot reach mail) and portal/login
   sample_support_content.html (not a form builder page). */
.icsynergy-form hr {
    height: 0;
    border: 0 !important;
    border-top: 1px solid var(--fb-border) !important;
    margin-top: 8px;
    margin-bottom: 8px;
}

/* rightfax_config pairs a navy separator with a 'border:1px dotted grey' one,
   so that form has two deliberate divider weights. Keep the distinction. */
.icsynergy-form hr[style*="dotted"] {
    border-top-style: dotted !important;
}

/* Option lists: scroll regions, so their height is a straight trade against
   the rest of the form. Trimmed rather than removed. */
.multiselect-list-group,
.multiselect-selected-list-group,
.query-select-list-group {
    max-height: 208px;
}

.icsynergy-form .dl-horizontal {
    margin-bottom: 4px;
}

.icsynergy-form .dl-horizontal dd {
    margin-bottom: 2px;
}

/* Drop the trailing gap under a subform's last field row. Anchored on the
   last row wrapper inside the form div - each wrapper holds one row, so
   :last-child on the row itself would match every single-widget row. */
.icsynergy-form .subform-panel > .panel > .panel-body > [data-icsynergy-form] > div:last-child .form-row.form-group {
    margin-bottom: 0;
}

/* ── Narrow viewports ───────────────────────────────────────────────────── */

@media (max-width: 767px) {
    /* Left-align only. The 15px .col-* padding must stay: .form-horizontal
       .form-group carries margin: 0 -15px, and that padding is what pulls the
       content back inside the container. Zeroing it put every label - in forms
       and subforms alike - 15px past the panel's content edge, flush against
       the border. */
    .icsynergy-form .control-label {
        text-align: left;
        margin-bottom: 2px;
    }

    .icsynergy-form .col-sm-2.control-label {
        padding-top: 0;
    }

    /* Touch targets win over density on a phone - restore comfortable
       control heights. */
    .icsynergy-form {
        --fb-control-h: 34px;
        --fb-row-gap: 10px;
    }

    .subform-panel > .panel > .panel-heading > .panel-title {
        flex-wrap: wrap;
    }

    .subform-panel .remove-form-btn {
        margin-left: 0;
    }
}

/* ══ AUDIT VIEWER ═══════════════════════════════════════════════════════════
   status_viewer/audit_viewer.html plus the detail fragments in
   status_viewer/_audit.html, which land in the SHARED #icrare2-modal from
   layout.html - hence the .audit-detail scope class rather than styling
   #icrare2-modal, which every other page also uses.

   The table is a DataTable (audit_viewer.js), so its sort classes and header
   markup are left alone; everything here is presentation on top.
   ═════════════════════════════════════════════════════════════════════════ */

/* Stood in for the <br/> that used to separate the panel from the page bottom. */
.audit-viewer-page > .row > .col-md-12 > .panel {
    margin-bottom: 18px;
}

/* ── Filter bar ─────────────────────────────────────────────────────────────
   Was a nested .panel.panel-default inside the panel body. Now a plain region
   closed by a hairline, matching the flattened search results (SR1). */

.audit-viewer-page .audit-filter-bar {
    padding-bottom: 4px;
    border-bottom: 1px solid var(--fb-hairline);
}

.audit-viewer-page .audit-filter-bar .form-group {
    margin-bottom: 10px;
}

.audit-viewer-page .audit-filter-bar label {
    margin-bottom: 3px;
    font-size: 12px;
    font-weight: 600;
    color: var(--fb-ink-muted);
}

/* The Search/Clear pair sat in an .input-group with the buttons as direct
   children, which is not a shape Bootstrap 3 supports - it only styles buttons
   inside .input-group-btn. Laid out as a plain flex pair instead, and aligned
   to the bottom of the row so they line up with the inputs rather than with the
   labels above them. */
.audit-viewer-page .audit-filter-bar .input-group:has(> .btn) {
    display: flex;
    gap: 6px;
}

.audit-viewer-page .audit-filter-bar .input-group > .btn {
    flex: 0 0 auto;
    background-color: #fff;
    background-image: none;
    border: 1px solid var(--fb-border);
    border-radius: 4px;
    color: #4f6277;
    font-size: 12.5px;
    font-weight: 600;
    text-shadow: none;
    box-shadow: none;
}

.audit-viewer-page .audit-filter-bar #audit-filter-submit {
    background-color: var(--fb-navy);
    border-color: var(--fb-navy);
    color: #fff;
}

/* ── Client-side table filter ───────────────────────────────────────────────
   Distinct from the server-side query above: audit_viewer.js drives
   DataTables' own search() from this input, so it filters what is already on
   screen. Labelled rather than sr-only so that difference is visible. */

.audit-viewer-page .audit-table-filter {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 10px;
    margin: 12px 0 10px;
}

.audit-viewer-page .audit-table-filter-label {
    margin: 0;
    font-size: 12px;
    font-weight: 600;
    color: var(--fb-ink-muted);
}

.audit-viewer-page .audit-table-filter .input-group {
    width: 320px;
    max-width: 100%;
}

/* ── Audit table ────────────────────────────────────────────────────────────
   Eight columns of mostly short values plus one long Message. table-bordered
   drew a full grid around every cell, which made the repetition (Group and
   Type are usually one value for a whole request) read as noise. Horizontal
   rules only, and a hover row so a wide row can be tracked across. */

/* No overflow container. #audit-table-html used to carry overflow-x:auto, which
   gave the table a scrollbar of its own, below the last row - and since paging
   is off (audit_viewer.js: paging:false, so a page is a whole server-side batch
   of up to 100 audits) reaching it meant scrolling to the very bottom of the
   result set. The table now simply fits its container at any width, like any
   other table on the site; see the wrapping rules further down, which are what
   make that true. */

.audit-viewer-page #audit-viewer-table.table-bordered,
.audit-viewer-page #audit-viewer-table.table-bordered > thead > tr > th,
.audit-viewer-page #audit-viewer-table.table-bordered > tbody > tr > td {
    border-left: 0;
    border-right: 0;
}

.audit-viewer-page #audit-viewer-table > thead > tr > th {
    padding: 7px 10px;
    background-color: var(--fb-tint);
    border-bottom: 1px solid var(--fb-border);
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: #4a5568;
    white-space: nowrap;
}

.audit-viewer-page #audit-viewer-table > tbody > tr > td {
    padding: 6px 10px;
    border-top: 1px solid var(--fb-hairline);
    font-size: 12.5px;
    color: #33475b;
    vertical-align: middle;
}

.audit-viewer-page #audit-viewer-table > tbody > tr:hover > td {
    background-color: var(--fb-tint-soft);
}

/* Action Date wraps between the date and the time, which frees up the widest
   nowrap column in the table for the columns that carry the content.

   Wrapping is a display concern only and does NOT affect the sort: the cell
   text is unchanged, and audit_viewer.js registers "DD-MMM-YYYY HH:mm:ss A"
   with $.fn.dataTable.moment() to sort this column. What would break the sort
   is changing the rendered FORMAT - the template's
   #temporals.format(..., 'dd-MMM-yyyy hh:mm:ss a') has to keep matching that
   pattern exactly. */
.audit-viewer-page #audit-viewer-table > tbody > tr > td:first-child {
    white-space: normal;
    color: #5a6b7d;
}

/* Row action button. One per row, and stock .btn-default made a column of grey
   gradient boxes that outweighed the data beside them. Same quiet pill as the
   other row-level actions in the refresh. */
.audit-viewer-page #audit-viewer-table .btn.view-audit-btn {
    padding: 2px 10px;
    background-color: #fff;
    background-image: none;
    border: 1px solid var(--fb-border);
    border-radius: 999px;
    color: #4f6277;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    text-shadow: none;
    box-shadow: none;
    transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}

.audit-viewer-page #audit-viewer-table .btn.view-audit-btn:hover,
.audit-viewer-page #audit-viewer-table .btn.view-audit-btn:focus {
    background-color: var(--fb-tint);
    border-color: #c3d2e0;
    color: var(--fb-navy);
}

.audit-viewer-page #audit-viewer-table .btn.view-audit-btn .glyphicon,
.audit-viewer-page #audit-viewer-table .btn.view-audit-btn [class^="fa-"],
.audit-viewer-page #audit-viewer-table .btn.view-audit-btn [class*=" fa-"] {
    margin-right: 4px;
    font-size: 10px;
    color: #7d9ab5;
}

/* Pagination footer. */
.audit-viewer-page .panel-footer {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    background-color: #fbfcfe;
    border-top: 1px solid var(--fb-hairline);
}

.audit-viewer-page .panel-footer .text-muted {
    margin-left: auto;
    float: none;
    font-size: 12px;
}

/* ══ AUDIT DETAIL (shared modal body) ═══════════════════════════════════════
   Scoped to .audit-detail, which _audit.html puts on each fragment root.
   #icrare2-modal itself is the shared modal from layout.html and must not be
   styled from here.

   Every field was a .list-group-item containing an <h4> label and a <p> value.
   The h4 rendered at 18px - LARGER and heavier than the 14px value it
   described - so the label/value hierarchy was inverted, and seven one-line
   facts measured 454px of a 1131px modal. Now a two-column grid with a small
   uppercase label, which is the same label treatment used elsewhere in the
   refresh.
   ═════════════════════════════════════════════════════════════════════════ */

.audit-detail .list-group {
    margin-bottom: 0;
}

.audit-detail .list-group-item {
    display: grid;
    grid-template-columns: minmax(140px, 210px) 1fr;
    gap: 2px 16px;
    /* start, not baseline: on a tall row (the Email Body Preview iframe, a
       wrapped multi-line message) baseline dropped the label to the bottom of
       the row, metres away from the field it names. */
    align-items: start;
    padding: 7px 12px;
    border-color: var(--fb-hairline);
}

.audit-detail .list-group-item-heading {
    margin: 0;
    /* The label is 11.5px against a 13px value, so top-aligning the two boxes
       leaves their first-line baselines ~1.5px apart. This puts them back on
       the same line for the ordinary one-line rows. */
    padding-top: 2px;
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    line-height: 1.5;
    color: var(--fb-ink-muted);
}

.audit-detail .list-group-item-text {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    color: #33475b;
    word-break: break-word;
}

/* Below the sm breakpoint the label stacks above its value rather than
   squeezing both into a narrow phone width. */
@media (max-width: 767px) {
    .audit-detail .list-group-item {
        grid-template-columns: 1fr;
    }
}

/* The data blocks (Request Flow Data, Assigned Data, Extended Data, email
   body) use dl > dt > h4 rather than list-group items. Same label treatment,
   and the <pre> gets bounded like .failure-trace does on the request page -
   these were unbounded, so a single audit could make the modal 1000px+ tall
   with a horizontally scrolling payload. */
.audit-detail dl {
    margin: 0;
    padding: 8px 12px;
    border-top: 1px solid var(--fb-hairline);
}

.audit-detail dl > dt {
    margin-bottom: 4px;
}

.audit-detail dl > dt > h4,
.audit-detail dl > dd > h4 {
    margin: 0;
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--fb-ink-muted);
}

.audit-detail dl > dd {
    margin-left: 0;
}

.audit-detail pre {
    max-height: 45vh;
    overflow: auto;
    margin: 0;
    padding: 8px 10px;
    background-color: #fbfcfe;
    border: 1px solid var(--fb-hairline);
    border-radius: 4px;
    font-size: 12px;
    line-height: 1.5;
    color: #33475b;
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: anywhere;
}

/* The two JSON-diff blocks are the exception: jdd.js aligns them line-for-line
   side by side, so wrapping them would break that alignment. They keep
   white-space: pre and scroll horizontally instead. */
.audit-detail pre#dataBefore,
.audit-detail pre#dataAfter {
    white-space: pre;
    word-break: normal;
    overflow-wrap: normal;
}

/* identity_audit leads with a resource name in a .label carrying inline
   padding; neutralise the inline sizing and present it as a heading pill. */
.audit-detail > h3 {
    margin: 0 0 10px;
    font-size: 14px;
}

.audit-detail > h3 > .label {
    padding: 4px 10px !important;
    background-color: var(--fb-pill-bg);
    border-radius: 999px;
    color: var(--fb-navy);
    font-size: 12px;
    font-weight: 600;
}

.audit-detail #email-preview {
    width: 100%;
    max-width: 100%;
    border: 1px solid var(--fb-hairline);
    border-radius: 4px;
    background-color: #fff;
}

/* These two rules are what replaced the scroll container that used to sit on
   #audit-table-html: together they keep the table inside its panel at any
   window width, so there is never anything to scroll.

   Short values stay on one line. Beyond keeping row heights even (they used to
   wrap mid-phrase, "Access / Request"), this is what protects the narrow
   columns: it holds each at its full value, so the auto layout has to hand the
   remaining space to Message and Filter below. Without it those two claim space
   in proportion to their max-content and squeeze Group down until
   "Self-Service" splits across two lines. */
.audit-viewer-page #audit-viewer-table > tbody > tr > td {
    white-space: nowrap;
}

/* Message and Filter are the two genuinely long columns, and the only ones that
   wrap - which is what lets the table shrink to fit. Measured on a 1180px
   panel: the nowrap columns above take 897px and these two settle at ~141px
   each, exactly filling the panel.

   overflow-wrap:anywhere rather than break-word, for the reason spelled out on
   #config-table below: break-word only breaks a word that alone exceeds the
   line and does not feed back into table min-content sizing, so the column
   would still demand its longest token. anywhere lets the unbreakable tokens
   these two are full of (IGUIDs, request numbers, hyphenated asset names, JSON
   fragments) wrap, so neither can ever force the table wider than its panel.

   Done with a class rather than :nth-child because four of the eight columns are
   conditional (displayAuditNumberColumn, displaySubjectColumn,
   displayOwnerColumn), so column indices differ between pages using this same
   fragment. */
.audit-viewer-page #audit-viewer-table > tbody > tr > td.audit-cell-wrap {
    white-space: normal;
    overflow-wrap: anywhere;
    min-width: 120px;
}

/* The skip-link target is focusable (tabindex="-1"), which also lets a mouse
   click focus it and ring the whole page. Ring on keyboard focus only. */
main#main-content:focus {
    outline: none;
}

main#main-content:focus-visible {
    outline: 2px solid var(--fb-link);
    outline-offset: -3px;
}

/* ── Configuration table ────────────────────────────────────────────────────
   Every column here holds a config identifier, and those identifiers are
   hyphenated, underscored or CamelCase - none of which CSS treats as a break
   opportunity. So each column's min-content was one whole name
   ("emergency-department-downtime-track-board-provisioning" alone wanted
   446px), the six of them summed past the panel's 1450px, and since
   .table{width:100%} is a floor rather than a cap for table-layout:auto the
   table simply grew and spilled out of the panel - taking the Asset and Update
   Time columns off-screen and giving the document a horizontal scrollbar.

   anywhere, not break-word: break-word only breaks a word that alone exceeds
   the line, and it does not feed back into table min-content sizing, so it
   left the width unchanged at 1667px. anywhere lets these names wrap and
   brings the table to 1422px, inside the panel. */
#config-table > thead > tr > th,
#config-table > tbody > tr > td {
    overflow-wrap: anywhere;
}

/* ══════════════════════════════════════════════════════════════════════════
   Page action bar
   ══════════════════════════════════════════════════════════════════════════
   A single row of page-level actions (Submit / View / Edit / Back ...) sitting
   above the page content. Bootstrap 3's stock .btn is a gradient-filled,
   drop-shadowed control whose default variant reads as heavier than the
   primary one next to it; strung together with plain whitespace they also
   wrap raggedly on a narrow screen. This flattens them onto the --fb palette,
   sets one clear primary, and lays them out with flex so wrapping stays even.

   Anything given .action-bar-trailing is pushed to the right end of the bar
   and separated by a rule - use it for actions that belong to a section
   further down the page rather than to the page itself. */

.page-action-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    margin-bottom: 20px;
    background-color: var(--fb-tint);
    border: 1px solid var(--fb-border);
    border-radius: 6px;
}

.page-action-bar .btn {
    background-image: none;
    box-shadow: none;
    text-shadow: none;
    border-radius: 4px;
    padding: 6px 14px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.4;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.page-action-bar .btn > .glyphicon,
.page-action-bar .btn > .fas,
.page-action-bar .btn > .far {
    margin-right: 6px;
    font-size: 12px;
}

.page-action-bar .btn-primary,
.page-action-bar .btn-primary:focus {
    background-color: var(--fb-navy);
    border-color: var(--fb-navy);
    color: #ffffff;
}

.page-action-bar .btn-primary:hover,
.page-action-bar .btn-primary:active,
.page-action-bar .btn-primary:focus:hover {
    background-color: var(--fb-link);
    border-color: var(--fb-link);
    color: #ffffff;
}

.page-action-bar .btn-default,
.page-action-bar .btn-default:focus {
    background-color: #ffffff;
    border-color: var(--fb-border);
    color: var(--fb-link);
}

.page-action-bar .btn-default:hover,
.page-action-bar .btn-default:active,
.page-action-bar .btn-default:focus:hover {
    background-color: var(--fb-tint-soft);
    border-color: var(--fb-rail);
    color: var(--fb-navy);
}

/* Filled action, same weight as .btn-primary: pages that carry a real primary
   action tend to have marked it .btn-success (Resubmit Request), and
   reclassifying the markup would be a behaviour change dressed as a style one. */
.page-action-bar .btn-success,
.page-action-bar .btn-success:focus {
    background-color: var(--fb-navy);
    border-color: var(--fb-navy);
    color: #ffffff;
}

.page-action-bar .btn-success:hover,
.page-action-bar .btn-success:active,
.page-action-bar .btn-success:focus:hover {
    background-color: var(--fb-link);
    border-color: var(--fb-link);
    color: #ffffff;
}

/* Destructive (Cancel Request). Red at rest so it is never mistaken for
   navigation, but a faded red - it sits behind a confirm modal and does not
   need to shout. Hover deepens to the full red. Same weighting the page-header
   button strip used before these pages moved onto the bar. */
.page-action-bar .btn-danger,
.page-action-bar .btn-danger:focus {
    background-color: #fdf2f1;
    border-color: #eec7c2;
    color: #b04a3d;
}

.page-action-bar .btn-danger:hover,
.page-action-bar .btn-danger:active,
.page-action-bar .btn-danger:focus:hover {
    background-color: #f8dcd8;
    border-color: #d0554a;
    color: #a32b1c;
}

/* Disabled has to beat all three fills above, hence the [disabled] qualifier
   rather than relying on source order. */
.page-action-bar .btn[disabled],
.page-action-bar .btn[disabled]:hover,
.page-action-bar .btn[disabled]:focus {
    background-color: #f3f5f8;
    border-color: #e2e8ef;
    color: #8a9bad;
    opacity: 1;
}

/* Keyboard focus has to stay visible now that the stock focus outline is
   competing with a flat fill. */
.page-action-bar .btn:focus-visible {
    outline: 2px solid var(--fb-link);
    outline-offset: 2px;
}

/* Wrapper, not the button itself - the separator rule has to be drawn on a box
   that isn't already carrying the button's own border. */
.page-action-bar .action-bar-trailing {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    padding-left: 16px;
    border-left: 1px solid var(--fb-border);
}

/* ── SHORT BARS COLLAPSE INTO THE HEADER ─────────────────────────────────────
   A full-width tinted bar earns its vertical space when it holds a row of
   actions. Holding one or two - which is what a user without the privileges
   for the rest sees, since every button here is behind a th:if - it is mostly
   empty box, so they go back where they lived before the bar existed: beside
   the title. Three or more stay on the bar.

   Which buttons survive is only known at render time, so the switch has to be
   CSS. .page-header-row wraps the header and the bar purely to give :has()
   something to flip; it is display:block by default, so a full bar flows
   exactly as it would without the wrapper.

   "Two or fewer" is read off the bar's element children rather than by
   counting .btn descendants, which CSS cannot do:

     :has(> .page-action-bar .btn)          at least one button, so an empty
                                            bar is left to the rule below
     :not(:has(> ... > :nth-child(3)))      at most two children
     :not(:has(> ... > * > .btn:not(:only-child)))
                                            no child is a wrapper holding more
                                            than one button, which would put
                                            the real total over two

   The one place children and buttons diverge is request_details, where the
   help popover beside a disabled Resubmit is a child of its own. It counts as
   an item here, which is the intent - two buttons plus an icon is already more
   than belongs on a title line. */
.page-header-row:has(> .page-action-bar .btn):not(:has(> .page-action-bar > :nth-child(3))):not(:has(> .page-action-bar > * > .btn:not(:only-child))) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    /* The header rule moves up to the wrapper: left on .page-header it would
       stop short at the title, underlining half a row. */
    margin: 40px 0 20px;
    padding-bottom: 9px;
    border-bottom: 1px solid #eee;
}

.page-header-row:has(> .page-action-bar .btn):not(:has(> .page-action-bar > :nth-child(3))):not(:has(> .page-action-bar > * > .btn:not(:only-child))) > .page-header {
    flex: 1 1 auto;
    margin: 0;
    padding: 0;
    border-bottom: 0;
}

.page-header-row:has(> .page-action-bar .btn):not(:has(> .page-action-bar > :nth-child(3))):not(:has(> .page-action-bar > * > .btn:not(:only-child))) > .page-header h1 {
    margin: 0;
}

/* Strip the bar back to just its buttons - no fill, no border, no padding, and
   no trailing separator to divide them from a row that is not there. The 8px
   gap between them is the bar's own and is deliberately left alone. */
.page-header-row:has(> .page-action-bar .btn):not(:has(> .page-action-bar > :nth-child(3))):not(:has(> .page-action-bar > * > .btn:not(:only-child))) > .page-action-bar,
.page-header-row:has(> .page-action-bar .btn):not(:has(> .page-action-bar > :nth-child(3))):not(:has(> .page-action-bar > * > .btn:not(:only-child))) > .page-action-bar > .action-bar-trailing {
    flex: 0 0 auto;
    margin: 0;
    padding: 0;
    background-color: transparent;
    border: 0;
}

/* On some of these bars every button is behind a th:if, so a user with none of
   the privileges renders the bar with no buttons at all - an empty tinted box
   with nothing in it. :empty will not do here: Thymeleaf leaves the indentation
   whitespace behind as a text node. */
.page-action-bar:not(:has(.btn)) {
    display: none;
}

/* Every leading button on these bars is behind a th:if, so a user without the
   privileges for any of them renders the trailing group as the bar's only
   child - one lone button pushed to the far right, with a separator rule
   dividing it from nothing. With nothing to trail, it stops trailing. */
.page-action-bar > .action-bar-trailing:first-child {
    margin-left: 0;
    padding-left: 0;
    border-left: 0;
}

/* Once the bar wraps, "right-aligned" is meaningless - the trailing group is
   on its own line, so drop the rule and let it sit flush left. */
@media (max-width: 767px) {
    .page-action-bar .action-bar-trailing {
        margin-left: 0;
        padding-left: 0;
        border-left: 0;
    }
}

/* ══ ACCESS CERTIFICATIONS ══════════════════════════════════════════════════
   my_list.html (the certifier's actionable list) and user_list.html (the
   read-only admin twin), both scoped by .certify-page.

   my_list is a DataTable, so its sort classes and generated header markup are
   left alone; everything here is presentation on top of them.

   The shape of the problem: eleven columns, a Details cell that is a stack of
   "Label: value" lines - so rows measured 177px tall - and the three decision
   controls at the far right vertically centred inside that height. A checkbox
   therefore floated in the middle of the row, a hand-span away from the name it
   belonged to, and two of the eleven columns were empty until it was ticked.
   ═════════════════════════════════════════════════════════════════════════ */

.certify-page > .row > .col-md-12 > .panel {
    margin-bottom: 18px;
}

/* Count beside the panel heading. Was .badge.alert-info - a Bootstrap badge
   wearing an alert's colours, which made it read as a warning. Same pill as the
   widget-header counts. */
.certify-page .certify-count-pill {
    display: inline-block;
    padding: 2px 9px;
    border-radius: 999px;
    background-color: #dfe9f3;
    color: var(--fb-link);
    font-size: 11px;
    font-weight: 700;
    line-height: 1.5;
}

/* Sits beside a disabled Submit and says what to do to enable it. Hidden by
   my_list.js as soon as anything is selected. */
.certify-page .certify-action-hint {
    font-size: 12.5px;
    color: var(--fb-ink-muted);
}

.certify-page .certify-submit-count {
    display: inline-block;
    min-width: 20px;
    margin-left: 4px;
    padding: 1px 7px;
    border-radius: 999px;
    background-color: rgba(255, 255, 255, 0.22);
    font-size: 11px;
    font-weight: 700;
    line-height: 1.5;
}

.certify-page .page-action-bar .btn[disabled],
.certify-page .page-action-bar .btn[disabled]:hover {
    background-color: #b6c4d2;
    border-color: #b6c4d2;
    color: #ffffff;
    opacity: 1;
}

/* ── Table ──────────────────────────────────────────────────────────────────
   Horizontal rules only and a hover row, matching the audit table: with eleven
   columns of mostly short values, a full grid drew more lines than data. */

.certify-page .certify-table > thead > tr > th {
    padding: 7px 10px;
    background-color: var(--fb-tint);
    border-bottom: 1px solid var(--fb-border);
    border-top: 0;
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: #4a5568;
    white-space: nowrap;
}

.certify-page .certify-table > tbody > tr > td {
    /* top, not middle. On a 177px row, middle put the checkbox and the action
       controls level with the fifth line of the Details cell while the name
       they act on sat at the top - the two halves of one decision were 80px
       apart vertically. Everything now starts on the row's first line. */
    vertical-align: top;
    padding: 9px 10px;
    border-top: 1px solid var(--fb-hairline);
    font-size: 12.5px;
    line-height: 1.5;
    color: #33475b;
}

.certify-page .certify-table > tbody > tr:hover > td {
    background-color: var(--fb-tint-soft);
}

/* ── User Information ───────────────────────────────────────────────────────
   One cell in place of the old Name / DOB / Lan ID / Email Address columns.
   Three lines, weighted by what you actually scan for: the name, then the
   identifiers you match a record against, then the address you only need once
   you have found the row. */

/* The percentage is a preference, the pixels a floor. Without the preference
   this column takes whatever is spare - on user_list, which has only four
   columns, it drew ~500px of largely empty space while Details wrapped. */
.certify-page .certify-table .certify-col-user {
    width: 22%;
    min-width: 230px;
}

.certify-page .certify-cell-user {
    line-height: 1.45;
}

.certify-page .certify-user-name {
    display: block;
    font-weight: 600;
    color: var(--fb-ink);
}

/* LAN ID and DOB share a line, separated by a middot drawn in CSS - the same
   grammar as .ics-panel-heading-qualifier, so the markup carries no
   punctuation. */
.certify-page .certify-user-meta {
    display: block;
    font-size: 11.5px;
    color: var(--fb-ink-muted);
}

.certify-page .certify-user-dob::before {
    content: "\00b7";
    margin: 0 6px;
    color: #b6c4d2;
}

/* Only when there is a LAN ID to separate it from - some records have none, and
   a leading middot would read as a missing value rather than as a separator. */
.certify-page .certify-user-lanid:empty + .certify-user-dob::before {
    content: none;
}

/* Rendered by CertifyController.emailAddressHtml(), which wraps every dot and
   @ in <span class="break"> so a long address can break at those points. Those
   breaks exist for addresses that genuinely need them; the column floor above
   keeps an ordinary one on a single line, since a wrap after the dot in
   "gmail. com" reads as a typo rather than as a wrap. */
.certify-page .certify-user-email {
    display: block;
    font-size: 11.5px;
    color: #5a6b7d;
    overflow-wrap: anywhere;
}

/* Records with no email address render this empty rather than "(unspecified)".
   Taken out of flow so the identity block is two lines rather than two lines
   and a gap. */
.certify-page .certify-user-email:empty {
    display: none;
}

/* The widest column and the only genuinely long one, so it is the column that
   absorbs the table's remaining width - and the one that has to wrap for the
   table to fit its panel at any width. Set slightly smaller and quieter than
   the identifying columns: it is reference material you read once you have
   found the row, not something you scan down. */
/* The floor matters. Details was first written as the table's release valve -
   the one column allowed to wrap to any width, so the table could always be
   squeezed to fit its panel. That does not survive a narrow window: eleven
   columns cannot fit 1200px however hard Details is squeezed, so it collapsed
   to ~80px and broke words down their middle ("Subcategor / y") while the table
   overflowed the panel anyway. The table scrolls instead (see the scroll
   container below), and this floor is what stops the squeeze. */
.certify-page .certify-table .certify-col-details {
    width: 24%;
    min-width: 200px;
}

/* user_list has four columns to my_list's eight, so there is real slack to
   distribute and auto layout was handing it to Entitlement and Expires - two
   columns of short values that grew to 332px and 315px of mostly white space.
   Scoped by the scroll wrapper, which only user_list has (my_list gets
   .dataTables_wrapper instead), so my_list's tighter balance is unaffected. */
.certify-page .certify-table-scroll .certify-col-details {
    width: 45%;
}

.certify-page .certify-cell-details {
    font-size: 12px;
    line-height: 1.55;
    color: #5a6b7d;
    /* break-word, not anywhere: at the floor above there is room for these
       words, and anywhere would still split them mid-syllable. This breaks only
       a token genuinely longer than the column. */
    overflow-wrap: break-word;
}

/* Dates line up digit-for-digit down the column, which is what makes a sorted
   list of them scannable. */
.certify-page .certify-cell-expires,
.certify-page .certify-cell-default-action {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Applied by my_list.js. The list is sorted by expiry, but sort order alone
   does not say whether the top row is due in four days or seven weeks. */
.certify-page .certify-cell-expires.is-expiring-soon {
    color: var(--fb-warn-ink);
    font-weight: 600;
}

.certify-page .certify-cell-expires.is-expiring-soon::after {
    content: "\f071";           /* fa-triangle-exclamation */
    margin-left: 6px;
    font-family: "Font Awesome 6 Free", "Font Awesome 5 Free";
    font-weight: 900;
    font-size: 10px;
    color: var(--fb-warn-rail);
}

.certify-page .certify-cell-expires.is-expired {
    color: var(--fb-danger);
    font-weight: 600;
}

/* ── Decision controls ──────────────────────────────────────────────────────
   The three right-hand columns: Action (checkbox), Your Action (select),
   Your Date (datepicker). The last two are empty until the checkbox is ticked,
   which read as two broken columns; an em rule now stands in for "no decision
   yet" so the emptiness looks deliberate. */

.certify-page .certify-table .certify-col-include {
    text-align: center;
}

.certify-page .certify-cell-include {
    text-align: center;
    /* Nudged down to sit on the first text line of the row rather than on the
       cap-height above it. */
    padding-top: 11px;
}

/* Was .form-control with an inline width:30% - a text-input treatment (34px
   tall, full border, focus glow) stretched across a checkbox, which rendered as
   a box of unpredictable size that moved with the column. */
.certify-page .certify-cell-include .select-certification {
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--fb-link);
    cursor: pointer;
}

.certify-page .certify-cell-include .select-certification:focus-visible {
    outline: 2px solid var(--fb-link);
    outline-offset: 2px;
}

.certify-page .certify-cell-decision {
    min-width: 132px;
}

.certify-page .certify-table > tbody > tr:not(.is-selected) .certify-cell-decision::before {
    content: "—";
    color: #b6c4d2;
}

/* :not(.hidden) on both of these is load-bearing. my_list.html's local .hidden
   collapses these controls to width:0/height:0 rather than display:none, and a
   plain descendant selector here outweighs that single class - sizing them
   unconditionally would make every row's controls visible. */
.certify-page .certify-cell-decision .choose-certification-action:not(.hidden) {
    width: 100%;
    min-width: 118px;
    height: var(--fb-control-h);
    padding: 3px 8px;
    font-size: 12.5px;
}

/* The defect this fixes: the group was sized by the column, which settled at
   86px - narrow enough that "2026-06-11" rendered as "2026-06". The day was
   cut off the one control that decides when someone's access ends. */
.certify-page .certify-cell-decision .input-group.date:not(.hidden) {
    width: 136px;
}

.certify-page .certify-cell-decision .input-group.date:not(.hidden) > .form-control {
    height: var(--fb-control-h);
    padding: 3px 8px;
    font-size: 12.5px;
    font-variant-numeric: tabular-nums;
    background-color: #ffffff;
    cursor: pointer;
}

.certify-page .certify-cell-decision .input-group.date:not(.hidden) > .input-group-addon {
    padding: 3px 9px;
    background-color: var(--fb-tint);
    border-color: var(--fb-border);
    color: #7d9ab5;
    cursor: pointer;
}

/* Parsley's range message for the date fields. It renders as a <ul> injected after the
   input, and these cells are ~136px wide, so left unstyled it forced the column wider than
   the control it describes. */
.certify-page .certify-cell-decision .parsley-errors-list {
    margin: 4px 0 0;
    padding: 0;
    max-width: 136px;
    list-style: none;
    font-size: 11px;
    line-height: 1.35;
    color: var(--fb-danger);
}

.certify-page .certify-cell-decision .parsley-error {
    border-color: var(--fb-danger);
}

/* ── Selected row ───────────────────────────────────────────────────────────
   Nothing used to mark a row you had decided on, so on a list of eleven the
   only record of your own progress was the scatter of ticked boxes in one
   narrow column. The rail is on the first cell because a border on <tr> is not
   drawn under border-collapse. */

.certify-page .certify-table > tbody > tr.is-selected > td {
    background-color: var(--fb-pill-bg);
}

.certify-page .certify-table > tbody > tr.is-selected:hover > td {
    background-color: #e0edf6;
}

.certify-page .certify-table > tbody > tr.is-selected > td:first-child {
    box-shadow: inset 3px 0 0 var(--fb-link);
}

/* ── DataTables chrome ──────────────────────────────────────────────────────
   The filter box was the stock right-floated "Search:" pair. Labelled in
   my_list.js and laid out here, matching the audit viewer's client-side filter.
   Note paging is off (my_list.js: paging:false), so this is the only way to
   narrow a long list. */

/* The Bootstrap DataTables integration puts the filter in the right-hand
   .col-sm-6 of a row whose left half holds the page-length menu - and paging is
   off here, so that half is empty and the filter sat marooned against the right
   edge. Widened to the full row so it reads as a control belonging to the table
   below it. */
.certify-page .dataTables_wrapper .row > .col-sm-6:has(> .dataTables_filter) {
    width: 100%;
    float: none;
}

/* The 10px matches the table cells' own horizontal padding, so the label starts
   on the same vertical line as the column headers below it. Without it the
   filter sat flush against the panel edge while every header was indented, and
   the two read as belonging to different boxes. Same for the row count. */
.certify-page .dataTables_wrapper .dataTables_filter {
    float: none;
    margin: 12px 0 10px;
    padding: 0 10px;
    text-align: left;
}

.certify-page .dataTables_wrapper .dataTables_filter label {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 10px;
    margin: 0;
    font-size: 12px;
    font-weight: 600;
    color: var(--fb-ink-muted);
}

.certify-page .dataTables_wrapper .dataTables_filter input {
    width: 320px;
    max-width: 100%;
    height: var(--fb-control-h);
    margin: 0;
    padding: 3px 10px;
    border: 1px solid var(--fb-border);
    border-radius: 4px;
    font-size: 12.5px;
    font-weight: 400;
    color: #33475b;
}

.certify-page .dataTables_wrapper .dataTables_info {
    padding: 6px 10px 0;
    font-size: 12px;
    color: var(--fb-ink-muted);
}

/* ── Empty state ────────────────────────────────────────────────────────────
   Was a bare <em>None</em>, which on the certifier's own page reads as though
   something failed to load rather than as the good outcome it is. */

.certify-page .certify-empty {
    padding: 34px 20px;
    text-align: center;
}

.certify-page .certify-empty-icon {
    font-size: 26px;
    color: #a8c4a0;
}

.certify-page .certify-empty-title {
    margin: 10px 0 2px;
    font-size: 14px;
    font-weight: 600;
    color: var(--fb-ink);
}

.certify-page .certify-empty-text {
    margin: 0;
    font-size: 12.5px;
    color: var(--fb-ink-muted);
}

/* ── Confirm dialog ─────────────────────────────────────────────────────────
   The list of pending changes is the substance of this dialog and was set as
   one run-on paragraph of <br>-separated sentences. The irreversibility line
   below it was styled identically to everything else. */

.certify-confirm-modal #submit-msg {
    margin-bottom: 10px;
    font-size: 13px;
    color: var(--fb-ink);
}

.certify-confirm-modal #submit-actions {
    margin-bottom: 12px;
    padding: 10px 12px;
    background-color: var(--fb-tint);
    border: 1px solid var(--fb-hairline);
    border-radius: 4px;
    font-size: 12.5px;
    line-height: 1.9;
    color: #33475b;
}

.certify-confirm-modal #submit-actions:empty {
    display: none;
}

.certify-confirm-modal .certify-confirm-warning {
    margin: 0;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--fb-warn-ink);
}

.certify-confirm-modal .certify-confirm-warning:empty {
    display: none;
}

/* ── Narrow screens ─────────────────────────────────────────────────────────
   Eleven columns will not fit a phone, and the alternative to scrolling the
   table is scrolling the whole document sideways. Bounded here so the scroll
   belongs to the table. */

/* ── Scroll container ───────────────────────────────────────────────────────
   Unconditional, not gated behind a breakpoint. Eleven columns want roughly
   1540px once every column has its floor, and the panel is narrower than that
   on any window under ~1640px - which is most of them. Gating this at 991px
   left every width in between with a table hanging 249px outside its own panel.

   Scoped to the element that holds the table, not to .dataTables_wrapper: the
   wrapper also contains the filter box and the row count, and those should stay
   put while the columns scroll under them. The Bootstrap DataTables integration
   renders .dataTables_wrapper > .row > .col-sm-12 > table, which is what the
   :has() below selects; .certify-table-scroll is the hand-written equivalent in
   user_list.html, which has no DataTable behind it. */
.certify-page .dataTables_wrapper .row > [class*="col-"]:has(> .certify-table),
.certify-page .certify-table-scroll {
    overflow-x: auto;
    /* macOS hides overlay scrollbars until something scrolls, so a table that
       had more columns off to the right looked simply truncated. These two
       force a persistent track, which is the only affordance saying the rest of
       the row is reachable. */
    scrollbar-width: thin;
    scrollbar-color: #c3d2e0 transparent;
}

.certify-page .dataTables_wrapper .row > [class*="col-"]:has(> .certify-table)::-webkit-scrollbar,
.certify-page .certify-table-scroll::-webkit-scrollbar {
    height: 9px;
}

.certify-page .dataTables_wrapper .row > [class*="col-"]:has(> .certify-table)::-webkit-scrollbar-thumb,
.certify-page .certify-table-scroll::-webkit-scrollbar-thumb {
    background-color: #c3d2e0;
    border-radius: 999px;
}

.certify-page .dataTables_wrapper .row > [class*="col-"]:has(> .certify-table)::-webkit-scrollbar-track,
.certify-page .certify-table-scroll::-webkit-scrollbar-track {
    background-color: var(--fb-tint);
}

/* ══ USER ACCOUNT ADMINISTRATION ═══════════════════════════════════════════
   ahs/search_user_tool/search_user_tool.html and its results fragment, scoped
   by .user-admin-page.

   The scope is load-bearing, not decorative: .existing-user-search-tool-results
   is also the table class on ahs/erecords_remove_requests/search.html, and the
   rules below must not reach it.

   These rules were a <style> block in the page head. Moved here so the page
   picks up the shared tokens (it was carrying its own greys - #ddd, #555, #666,
   #777 - none of which matched the palette the rest of the refresh uses) and so
   the table can be treated like the audit and certify tables.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Panels ─────────────────────────────────────────────────────────────────
   Three stacked panels were three different Bootstrap contexts - panel-primary,
   panel-info, panel-default - so they read as three unrelated kinds of thing.
   All primary now; these only handle the spacing between them. */

.user-admin-page .panel {
    margin-bottom: 18px;
}

.user-admin-page .search-tool-actions-panel {
    margin-top: 0;
}

/* ── Find Users ─────────────────────────────────────────────────────────────
   The two search submit buttons are styled by the shared "search submit is the
   primary action" rule further up, which .search-tool-basic-btn and
   .search-tool-advanced-btn were added to - one definition of that idea rather
   than a second copy here. The basic/advanced toggle is likewise the shared
   .search-mode-switch.

   Clear Filters is the only thing left that is specific to this page: it sits
   inside the advanced form's .input-group-btn beside the submit, where adjacent
   buttons are deliberately seamed together by Bootstrap. It is a separate,
   non-submitting action, so it gets separated - previously by an inline
   margin-left:50px on the button itself. */
.user-admin-page #clear-filter {
    margin-left: 14px;
    background-image: none;
    box-shadow: none;
    text-shadow: none;
    background-color: #fff;
    border: 1px solid var(--fb-border);
    border-radius: 4px;
    color: #4f6277;
    font-size: 12.5px;
    font-weight: 600;
}

.user-admin-page #clear-filter:hover,
.user-admin-page #clear-filter:focus {
    background-color: var(--fb-tint);
    border-color: var(--fb-rail);
    color: var(--fb-navy);
}

.user-admin-page #clear-filter > .glyphicon {
    margin-right: 5px;
    font-size: 11px;
    color: #7d9ab5;
}

/* ── Advanced search form ───────────────────────────────────────────────────
   The operand dropdown is handled by the shared rule further up, which this
   form's class was added to. What is left is the controls around it.

   This page is NOT inside .icsynergy-form, so none of the form builder's input
   and label treatment reached it - which is why these rows were stock Bootstrap
   3 (34px controls, 14px labels, blue glow focus) sitting under a heading that
   had already been refreshed. These rules bring the page level with the widget
   rather than inventing anything new: the values are the form builder's own. */

.user-admin-page .user-search-tool-advanced-form .control-label {
    padding-top: 6px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--fb-ink);
}

.user-admin-page .user-search-tool-advanced-form .control-label .glyphicon-question-sign {
    color: var(--fb-ink-muted);
    transition: color 0.12s;
}

.user-admin-page .user-search-tool-advanced-form .control-label a:hover .glyphicon-question-sign,
.user-admin-page .user-search-tool-advanced-form .control-label a:focus .glyphicon-question-sign {
    color: var(--fb-navy);
}

/* Height on all three input-group participants together, so the operand button
   and the value input stay flush - the same grouping the form builder uses. */
.user-admin-page .user-search-tool-advanced-form input.form-control,
.user-admin-page .user-search-tool-advanced-form .input-group-btn > .btn {
    height: var(--fb-control-h);
    padding-top: 3px;
    padding-bottom: 3px;
    font-size: 13px;
    line-height: 1.5;
}

.user-admin-page .user-search-tool-advanced-form .form-control {
    border-color: var(--fb-border);
    box-shadow: none;
    transition: border-color 0.12s, box-shadow 0.12s;
}

.user-admin-page .user-search-tool-advanced-form .form-control:hover:not([disabled]) {
    border-color: #b9c7d7;
}

/* Focus ring in the navy tint rather than Bootstrap's default blue glow. */
.user-admin-page .user-search-tool-advanced-form .form-control:focus {
    border-color: var(--fb-navy);
    box-shadow: 0 0 0 3px rgba(0, 44, 78, 0.12);
}

.user-admin-page .user-search-tool-advanced-form .form-control::placeholder {
    color: #9fb0c2;
}

/* Rows were spaced by Bootstrap's 15px form-group margin, which on a ten-row
   form is a lot of scrolling for very little content. */
.user-admin-page .user-search-tool-advanced-form .form-group {
    margin-bottom: var(--fb-row-gap);
}

/* ── Results table ──────────────────────────────────────────────────────────
   Eleven columns. Same treatment as the audit and certify tables: uppercase
   hairline header, horizontal rules only, hover row. */

/* Eleven columns want ~1520px once the headers stop wrapping, and the panel is
   narrower than that on most windows - so the table scrolls inside the panel
   rather than spilling out of it and giving the whole document a horizontal
   scrollbar. #search-tool-results-table is the div search_user_tool.js renders
   the results fragment into, so it survives every re-search.

   The forced scrollbar track matters more here than elsewhere: macOS hides
   overlay scrollbars until something scrolls, and User Status is the column
   that ends up off the right edge. */
.user-admin-page #search-tool-results-table {
    overflow-x: auto;
    scrollbar-width: thin;
    scrollbar-color: #c3d2e0 transparent;
}

.user-admin-page #search-tool-results-table::-webkit-scrollbar {
    height: 9px;
}

.user-admin-page #search-tool-results-table::-webkit-scrollbar-thumb {
    background-color: #c3d2e0;
    border-radius: 999px;
}

.user-admin-page #search-tool-results-table::-webkit-scrollbar-track {
    background-color: var(--fb-tint);
}

.user-admin-page .existing-user-search-tool-results > thead > tr > th {
    padding: 7px 10px;
    background-color: var(--fb-tint);
    border-bottom: 1px solid var(--fb-border);
    border-top: 0;
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: #4a5568;
    /* Every multi-word header here wrapped to two lines - "Employee / ID",
       "Job Description/ / Title", "AHS Network / Account" - which set the header
       row's height from the longest of them and made the row hard to scan. */
    white-space: nowrap;
}

.user-admin-page .existing-user-search-tool-results > tbody > tr > td {
    padding: 9px 10px;
    border-top: 1px solid var(--fb-hairline);
    font-size: 12.5px;
    line-height: 1.5;
    color: #33475b;
    vertical-align: top;
}

.user-admin-page .existing-user-search-tool-results > tbody > tr:hover > td {
    background-color: var(--fb-tint-soft);
}

/* Selection. The whole row is clickable (search_user_tool.js binds the row and
   defers to the radio), so the selected state has to be legible across all
   eleven columns - the rail marks where it starts. */
.user-admin-page .existing-user-search-tool-results > tbody > tr {
    cursor: pointer;
}

.user-admin-page .existing-user-search-tool-results > tbody > tr.is-selected > td {
    background-color: var(--fb-pill-bg);
}

.user-admin-page .existing-user-search-tool-results > tbody > tr.is-selected:hover > td {
    background-color: #e0edf6;
}

.user-admin-page .existing-user-search-tool-results > tbody > tr.is-selected > td:first-child {
    box-shadow: inset 3px 0 0 var(--fb-link);
}

.user-admin-page .ua-cell-user {
    min-width: 170px;
}

.user-admin-page .ua-user-label {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 0;
    font-weight: 600;
    color: var(--fb-ink);
    cursor: pointer;
}

.user-admin-page .ua-cell-user .userRadio {
    flex: 0 0 auto;
    margin: 0;
    accent-color: var(--fb-link);
}

.user-admin-page .ua-cell-iguid .label {
    display: inline-block;
    padding: 3px 8px;
    background-color: var(--fb-pill-bg);
    border-radius: 999px;
    color: var(--fb-navy);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.3px;
}

/* ── Stacked label/value cells (Email, AD Info) ─────────────────────────────
   Built by SearchUserToolController.labelledValue(). Was "<b>Label: </b>value"
   per line, which made the label - identical on every row - heavier than the
   address or date it named. Same inversion the audit detail panel had, and the
   same fix: small uppercase label, value at full weight. */

.user-admin-page .ua-cell-stacked {
    min-width: 190px;
}

.user-admin-page .ua-kv {
    display: block;
    margin-bottom: 5px;
}

.user-admin-page .ua-kv:last-child {
    margin-bottom: 0;
}

.user-admin-page .ua-kv-label {
    display: block;
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    line-height: 1.4;
    color: var(--fb-ink-muted);
}

.user-admin-page .ua-kv-value {
    display: block;
    font-size: 12.5px;
    line-height: 1.4;
    color: #33475b;
    overflow-wrap: anywhere;
}

/* ── Actions ────────────────────────────────────────────────────────────────
   The three groups (View / Manage / Admin) keep the shape last release gave
   them; this is the palette and the button treatment catching up with the
   action bar. */

.user-admin-page .search-tool-actions-header {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 15px;
    justify-content: space-between;
    margin-bottom: 14px;
}

.user-admin-page .search-tool-selection-state {
    margin: 0;
    font-size: 12.5px;
    color: var(--fb-ink-muted);
}

.user-admin-page .search-tool-selection-state strong {
    color: var(--fb-ink);
}

.user-admin-page .search-tool-action-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.user-admin-page .search-tool-action-group {
    flex: 1 1 280px;
    min-width: 0;
    padding: 12px 14px;
    background-color: var(--fb-tint-soft);
    border: 1px solid var(--fb-border);
    border-radius: 6px;
}

.user-admin-page .search-tool-action-group-title {
    margin: 0 0 10px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: var(--fb-ink-muted);
}

/* Destructive group. Was a pink fill (#fcf8f8) plus a pink border, which tinted
   the whole box before anything had been done; the rail carries the same
   warning with less shouting. */
.user-admin-page .search-tool-action-group-danger {
    background-color: #fdf9f9;
    border-color: #e6cdd0;
    box-shadow: inset 3px 0 0 var(--fb-danger);
}

/* Buttons laid out with the group's own gap rather than a margin on each. */
.user-admin-page .search-tool-action-group {
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    gap: 8px;
}

.user-admin-page .search-tool-action-group-title {
    flex: 0 0 100%;
}

.user-admin-page .search-tool-action-group .search-tool-btn {
    margin: 0;
    background-image: none;
    box-shadow: none;
    text-shadow: none;
    border-radius: 4px;
    padding: 5px 12px;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.4;
    background-color: #fff;
    border: 1px solid var(--fb-border);
    color: var(--fb-link);
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.user-admin-page .search-tool-action-group .search-tool-btn:hover:not([disabled]) {
    background-color: var(--fb-tint);
    border-color: var(--fb-rail);
    color: var(--fb-navy);
}

.user-admin-page .search-tool-action-group .search-tool-btn.btn-primary {
    background-color: var(--fb-navy);
    border-color: var(--fb-navy);
    color: #fff;
}

.user-admin-page .search-tool-action-group .search-tool-btn.btn-primary:hover:not([disabled]) {
    background-color: var(--fb-link);
    border-color: var(--fb-link);
    color: #fff;
}

.user-admin-page .search-tool-action-group .search-tool-btn > .glyphicon,
.user-admin-page .search-tool-action-group .search-tool-btn > .fas {
    margin-right: 5px;
    font-size: 11px;
}

/* These buttons ship disabled and are enabled by search_user_tool.js once a row
   is selected, so the disabled state is the first thing seen and has to read as
   "not yet" rather than as broken. */
.user-admin-page .search-tool-action-group .search-tool-btn[disabled] {
    background-color: #f4f7fa;
    border-color: #e3e9f0;
    color: #a8b6c4;
    opacity: 1;
}

.user-admin-page .search-tool-action-group .search-tool-btn:focus-visible {
    outline: 2px solid var(--fb-link);
    outline-offset: 2px;
}

.user-admin-page .search-tool-results-empty {
    padding: 18px 14px;
    font-size: 12.5px;
    color: var(--fb-ink-muted);
}

.user-admin-page .search-tool-results-empty h5 {
    margin: 0;
    font-size: 13px;
    color: var(--fb-ink);
}

/* ═══ PAGE-LEVEL ALERTS ═══════════════════════════════════════════════════════
   The success / warning / error banners at the top of layout.html and
   external-layout.html, plus every .alert-* notice in the ~60 templates that
   render one.

   Before this block they were stock Bootstrap 3 plus bootstrap-theme.min.css,
   which is the loudest thing the theme ships: a vertical gradient fill, a white
   text-shadow, an inset white highlight, and a saturated 1px border. Beside the
   flat #f0f4f8 panel headings and the hairline buttons, a success banner read as
   a different product.

   The four tones now use the accent-rail language already established by the
   subform panels (.panel-success rail #6cbf8b, .panel-info #5aa8c4,
   .panel-danger #d98b84) and by --fb-warn-rail #d99f2b. Tone lives on a 3px
   rail, a quiet tint, and one glyph; the message text itself stays near-neutral
   so it reads at the same weight in all four tones:

     tone      rail+glyph  fill       border     label ink
     success   #3f9c62     #f2faf5    #bddfca    #256b3a
     info      #3f8fae     #f1f8fb    #b6d9e6    #1c5d75
     warning   #ad7c1b     #fdf8ec    #f0e2c0    #5c4a20
     danger    #c96a61     #fdf2f1    #efc4c4    #9f2f2f

   The rails are the subform hues darkened about one step. The subform rails sit
   on white and always have a text badge beside them, so tone there is redundant
   and 2.2:1 is fine. Here the fill is already tinted AND most of the ~60
   templates render a bare notice with no "Warning" / "Error" label word, which
   leaves the rail and the glyph as the only tone signal - so both have to clear
   the 3:1 of WCAG 1.4.11 non-text contrast. As shipped they are 3.2:1 to 3.5:1
   against their own fill and against white. Message text is 8.7:1 or better in
   all four tones.

   The glyphs are inline SVG data URIs, not Font Awesome: external-layout.html
   (login, SSPR, forgot-password) loads icamp-style.css but NOT
   fontawesome/all.min.css, so an icon-font pseudo-element renders as tofu on
   exactly the pages where an error banner matters most.

   Selectors are .alert.alert-success, not .alert-success. home.html reuses the
   alert colour classes on Bootstrap badges (.badge.alert-info for the work item
   counts, .badge.alert-warning for the password-expiry pill), and those must
   keep the plain Bootstrap fill - a rail and a 40px icon gutter on a pill is
   not a small break.
   ═════════════════════════════════════════════════════════════════════════ */

.alert {
    /* bootstrap-theme.min.css puts a gradient, a text-shadow and an inset
       highlight on .alert; all three have to go before the tint reads flat. */
    background-image: none;
    text-shadow: none;
    box-shadow: none;

    /* Left is the rail; the tone blocks below only recolour it. Right leaves
       room for the dismiss button, which floats. */
    padding: 11px 34px 11px 40px;
    margin-bottom: 14px;
    border: 1px solid var(--fb-border);
    border-left: 3px solid var(--fb-rail);
    border-radius: 6px;
    background-color: var(--fb-tint-soft);
    background-repeat: no-repeat;
    background-position: 13px 12px;
    background-size: 15px 15px;
    color: #33475b;
    font-size: 13.5px;
    line-height: 1.5;
}

/* The label line - <strong>Success</strong> ahead of the <p> in both layouts.
   Already on its own line because the message is a block; saying so here lets
   the gap between label and message be controlled. */
.alert > strong:first-child,
.alert > b:first-child,
.alert > .alert-heading,
.alert > h4 {
    display: block;
    margin: 0 0 2px;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.1px;
}

.alert > p:last-child,
.alert > ul:last-child,
.alert > ol:last-child {
    margin-bottom: 0;
}

.alert hr {
    margin: 8px 0;
    border-top-color: rgba(0, 0, 0, 0.08);
}

.alert a,
.alert .alert-link {
    color: var(--fb-link);
    font-weight: 600;
    text-decoration: underline;
}

/* Dismiss button. Bootstrap sizes it 21px, floats it right and pulls it
   right: -21px into a 35px padding gutter; the padding here is our own, so the
   offset is reset and the glyph sits in the 34px we reserved. Stock opacity is
   0.2, which on a tint this light is about 1.3:1 - well under the 3:1 WCAG
   1.4.11 asks of a control. 0.65 puts the worst tone at 3.5:1. */
.alert-dismissible .close,
.alert-dismissable .close {
    position: relative;
    top: -1px;
    right: -24px;
    color: inherit;
    text-shadow: none;
    font-size: 19px;
    font-weight: 400;
    line-height: 1;
    opacity: 0.65;
    transition: opacity 0.12s;
}

.alert-dismissible .close:hover,
.alert-dismissible .close:focus,
.alert-dismissable .close:hover,
.alert-dismissable .close:focus {
    color: inherit;
    opacity: 1;
}

.alert-dismissible .close:focus-visible,
.alert-dismissable .close:focus-visible {
    outline: 2px solid var(--fb-link);
    outline-offset: 2px;
    opacity: 1;
}

/* ── Tones ───────────────────────────────────────────────────────────────── */

.alert.alert-success {
    border-color: #bddfca;
    border-left-color: #3f9c62;
    background-color: #f2faf5;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='8' fill='%233f9c62'/%3E%3Cpath d='M4.4 8.3l2.3 2.3 4.9-5.1' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.alert.alert-info {
    border-color: #b6d9e6;
    border-left-color: #3f8fae;
    background-color: #f1f8fb;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='8' fill='%233f8fae'/%3E%3Ccircle cx='8' cy='4.5' r='1.05' fill='%23fff'/%3E%3Cpath d='M8 7.1v4.6' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
}

.alert.alert-warning {
    border-color: #f0e2c0;
    border-left-color: #ad7c1b;
    background-color: var(--fb-warn-tint);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='8' fill='%23ad7c1b'/%3E%3Cpath d='M8 4.1v5' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round'/%3E%3Ccircle cx='8' cy='11.6' r='1.05' fill='%23fff'/%3E%3C/svg%3E");
}

.alert.alert-danger {
    border-color: #efc4c4;
    border-left-color: #c96a61;
    background-color: #fdf2f1;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='8' fill='%23c96a61'/%3E%3Cpath d='M5.5 5.5l5 5M10.5 5.5l-5 5' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
}

/* Label ink carries the tone. The message body stays #33475b in all four, so
   an error is not also harder to read than a success. */
.alert.alert-success > strong:first-child,
.alert.alert-success > b:first-child,
.alert.alert-success > .alert-heading,
.alert.alert-success > h4 { color: #256b3a; }

.alert.alert-info > strong:first-child,
.alert.alert-info > b:first-child,
.alert.alert-info > .alert-heading,
.alert.alert-info > h4 { color: #1c5d75; }

.alert.alert-warning > strong:first-child,
.alert.alert-warning > b:first-child,
.alert.alert-warning > .alert-heading,
.alert.alert-warning > h4 { color: var(--fb-warn-ink); }

.alert.alert-danger > strong:first-child,
.alert.alert-danger > b:first-child,
.alert.alert-danger > .alert-heading,
.alert.alert-danger > h4 { color: #9f2f2f; }

/* Bootstrap colours the whole alert body per tone at 0,1,0 specificity, which
   otherwise beats the neutral .alert colour above on source order alone. */
.alert.alert-success,
.alert.alert-info,
.alert.alert-warning,
.alert.alert-danger {
    color: #33475b;
}

/* The banner strip in layout.html and external-layout.html. A single flash
   message needs no bottom margin - the next thing down is the page content,
   which brings its own spacing. */
.iam-main-wrapper > .container-fluid > .alert:last-child {
    margin-bottom: 0;
}

@media (max-width: 767px) {
    .alert {
        padding: 10px 30px 10px 34px;
        background-position: 11px 11px;
        background-size: 14px 14px;
    }

    .alert-dismissible .close,
    .alert-dismissable .close {
        right: -21px;
    }
}
