/*
                                                            
    @@@@       @@@@@@@@@@@@@@@@@@@@@@@@@@@                   
    @@@@@@@@   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@              
    @@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@            
    @@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@          
    @@@@@@@@@  @@@@@@@@                     @@@@@@@@@@         
    @@@@@@@@@  @@@@@@@@                      @@@@@@@@@         
    @@@@@@@@@  @@@@@@@@                      @@@@@@@@@         
    @@@@@@@@@  @@@@@@@@                    @@@@@@@@@@          
    @@@@@@@@@  @@@@@@@@@@@@@@@@@@@    @@@@@@@@@@@@@@           
    @@@@@@@@@  @@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@             
    @@@@@@@@@  @@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@             
    (@@@@@@@@@                          @@@@@@@@@@@@@@         
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     
                ,@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@       
                
            LIGHTS | CONTROL | RIGGING
                ---- PREP PORTAL ---- 
            COBAIN SCHOFIELD 2021-Present
            -----------------------------
                  General stylesheet
            -----------------------------
    
// ----------------------------------------------------
// REVISION HISTORY
// ----------------------------------------------------
// - 08/10/2025 - Major restructuring from Portal v1 CSS
// - 12/12/2025 - Flash highlight effect for form fields added
// - 03/03/2026 - Added Wobble animations (linked to Wobble() function in General.js)
// - 29/07/2026 - Added timeline styling
// - 05/09/2026 - Fixed navbar height increasing to accomodate font size increase on hover (due to scale 1.2)
// - 20/09/2026 - Added .job-pal-logo (the job PAL logo shown top-right on the job pages and label spreadsheets)
// - 23/09/2026 - Added .pull-list-* styling for the job Pull Lists page (record type badges, sub-hire notes, component rows)
// - 25/09/2026 - Pull list "seen" tick column - strike-thru ticked rows, whole-cell tap target, quantity-changed note
// - 27/09/2026 - Added .equipment-* styling for the job Equipment Requests page and Equipment Request Items admin page 
// - 27/09/2026 - Added the shared offline mode styles (.spreadsheet-row-offline-marker, .offline-upload-new-rows)
// - 28/09/2026 - Added .MVR_Rig_Conflicts_Scroll for the MVR Details modal's Fixture ID / patch conflicts table
// - 29/09/2026 - Added .label-fixture-cell-warning (fixture label spreadsheet values that don't fit their label), .label-fixture-label-cell
//                (its read-only Label column) and .label-inventory-links-note
// - 29/09/2026 - Added .mvr-local-names-search for the MVR Inventory Map's Local Names tab
// - 29/09/2026 - Added .pdf-editor-column-options for the PDF Template Editor's table column options row
// - 29/09/2026 - Replaced .job-top-tabs with .job-nav-* for the job navigation bar - own classes so the sidebar's nav-link
//                and .nav-tabs hover rules no longer restyle/resize it, and it wraps on a phone instead of clipping its menus
// - 30/09/2026 - Added .network-* styling for the job Network page (device cards, port/interface rows, VLAN colour swatches
//                and trunk VLAN chips) and the Network Device Models admin page
// - 30/09/2026 - Added .network-wiring-* for the Label Network Wiring page (scaled label preview, role tick-box chips)
// - 30/09/2026 - Added .network-device-tile/.network-tile-port (the job Network page's small device cards, a dot per port
//                in its colour) and .network-device-detail; removed the unused .network-device divider
// - 30/09/2026 - Added .network-pe-* for the job Network page's Process Engines tab (input rows, priority, Switch control)
//                and .network-dmx-universe for LumiNode DMX ports
// - 30/09/2026 - Added .network-connection for the job Network page's Connected To column
// - 30/09/2026 - Added .network-default-* for the Label Network Wiring page's Default Port Setup card
// - 30/09/2026 - Job Network page: a device's IP interfaces are a band above its ports (.network-interface-grid, each
//                .network-interface a box, .network-interface-add) instead of a side column, so the ports table gets the
//                card's full width
// - 30/09/2026 - Job Network page: .network-cards tiles the rack/device cards (flex, wrapping, each as wide as it needs;
//                .network-card-open takes the full width), with fixed-width .network-device-tile-slot tiles
// - 30/09/2026 - Job Network page: composite rack cards (.network-composite-name, .network-composite-members - a section per
//                label, side by side as they fit)
// - 01/10/2026 - Job Universe View page: .universe-* (stat cards, universe list, the 512 channel grid, fixture blocks, clash hatching and lanes)
// - 01/10/2026 - Job Universe View page: .has-clash makes a universe list item red
// - 01/10/2026 - Added .job-nav-palettes, the job navigation bar's Palettes dropdown (position palette swatches)
// ----------------------------------------------------

*/

/* Top-level font size adjustment */

html {

    font-size: 80%; /* Reduce the overall rem reference from Boostrap to 0.8 */
    transition: font-size 0.5s ease-in-out; /* Smooth transition when font-size is changed in user preferences */

}

body {
    
    font-family: 'Nunito', Arial;
    
}

/*-----------------------------------------------------*/

/* Text Styling */
h1, h2, h3, h4, h5, h6 {
    
    font-family: 'Bebas Neue', sans-serif;
    padding-top: 0.5rem;
    
}

p + h1, p + h2, p + h3, p + h4, p + h5, p + h6 {

    margin-top: 1.5rem;
    border-top: 0.1rem solid #d1d1d1;
    padding-top: 1.5rem;

}

h1 i, h2 i, h3 i, h4 i, h5 i, h6 i {

    color: #2e82d1;

}

main > h1:first-of-type, main .col h1:first-of-type {

    border-left: 0.5rem solid #2e82d1;
    padding-left: 1rem;

}

p {
    
    font-family: 'Nunito', Arial;
    
}

.Brand_Text {
    
    font-family: "Bebas Neue";
    font-size: 1.5rem;
    
}

.smaller {
    
    font-size: 0.75rem;
    
}

/*-----------------------------------------------------*/

/* Badge and Pill Sizing */
.badge-large, .pill-large {

    font-size: 1rem;
    padding: 0.25rem 0.5rem;

}


/*-----------------------------------------------------*/

/* Authentication Page Background Animation */
.authentication-bg {

    background: rgb(27,117,187); 
    background: linear-gradient(30deg, rgba(27,170,187,0.65) 0%, rgba(27,117,187,0.65) 41%, rgba(26,34,93,0.65) 100%); 
    background-size: 250% 250%;
    animation: background-gradient-animation 5s ease infinite;
    height: 100vh;
    
}

@keyframes authentication-gradient {
    0% {
        background-position: 25% 50%;
    }
    50% {
        background-position: 100% 50%;
    }
    100% {
        background-position: 25% 50%;
    }
}

/*-----------------------------------------------------*/

/* Jumbotron Background Animation */
.jumbotron {

    background: linear-gradient(
        210deg, 
        rgb(217, 237, 255) 0%, 
        rgb(149, 196, 236) 50%, 
        rgb(157, 209, 255) 100%
    );
    background-size: 1000% 1000%;
    animation: background-gradient-animation 7.5s ease infinite;
    position: relative; 
    border: none;           /* Border removed to make way for animated border */
    padding: 2rem;          /* Padding for the ::before pseudo-element */
    margin-top: 0.5rem;

}

.jumbotron::before {

    content: '';
    position: absolute;     /* Position the border layer behind the jumbotron content */
    top: -0.2rem;           /* Offset for the border thickness */
    left: -0.2rem;
    bottom: -0.2rem;
    right: -0.2rem;
    z-index: -1;            /* Ensure it stays behind the jumbotron content */
    background: linear-gradient(
        210deg, 
        rgba(27,170,187, 1) 0%, 
        rgba(27,117,187, 1) 41%, 
        rgba(26,34,93, 1) 100%
    );
    background-size: 1000% 1000%;
    animation: background-gradient-animation 7.5s ease infinite;

}

@keyframes background-gradient-animation {

    0% {
        background-position: 25% 50%;
    }
    50% {
        background-position: 100% 50%;
    }
    100% {
        background-position: 25% 50%;
    }

}

/*-----------------------------------------------------*/

/* Navigation Bar Styling */

.logo {
    height: 3rem;
}

.navbar-brand {
    
    padding-top: .75rem;
    padding-bottom: .75rem;
    font-size: 1rem;
    box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);
    transition: 0.5s opacity ease-out, 0.5s transform ease-out;

}

.navbar-brand:hover {
    
    opacity: 0.7;
    color: white;
    text-decoration: none;
    transition: 0.15s opacity ease-out;
   
}

.navbar-brand img {

    transform: scale(1);
    transition: 0.5s transform ease-out;

}

.navbar-brand:hover img {

    transform: scale(1.05);
    transition: 0.15s transform ease-out;
    
}

.navbar .navbar-toggler {

    top: .25rem;
    right: 1rem;

}

.navbar .form-control {
    
    padding: 1.5rem;
    border-width: 0;
  
}

.navbar .form-control-dark {

    color: #fff;
    background-color: #6c757d;
    border-color: #6c757d;
    transition: 0.5s background-color ease-out;

}

.navbar .form-control-dark::placeholder {
 
    color: #b0b0b0;
    
}

.navbar .form-control-dark:focus {

    border-color: transparent;
    box-shadow: 0 0 0 3px rgba(255, 255, 255, .25);
    background: white;
    color: #495057;
    transition: 0.15s background-color ease-out;

}

.navbar .input-group-append a.va-middle {
        
    display: inline-flex;
    align-items: center;
    
}

/*-----------------------------------------------------*/

/* Sortable table headers */
th.sortable-header {

    cursor: pointer;
    user-select: none;

}

th.sortable-header .sort-indicator {

    margin-left: 0.35rem;
    font-size: 0.9em;
    letter-spacing: -0.08em;

}

th.sortable-header .sort-indicator.sort-neutral {

    color: #8b97a3;

}

th.sortable-header .sort-indicator.sort-active {

    opacity: 1;

}

th.sortable-header.sorting-active {

    /* no colour override — inherits header text colour */

}

/*-----------------------------------------------------*/

/* Footer Styling */

.footer {

    position: absolute;
    bottom: 0;
    width: 100%;
    background: #eceff5;
    box-shadow: inset -1px 0 0 rgb(0 0 0 / 10%);
    text-align: center;
    padding: 0.5rem auto;

}

/*-----------------------------------------------------*/

/* Sidebar Navigation Styling */

.sidebar {

    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 100;                                      /* Behind the navbar */
    padding: 3.5rem 0 0;                                 /* Height of navbar */
    box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
    font-size: 0.95rem;

}
    
.sidebar-sticky {

    position: relative;
    height: 100%;
    padding-top: 1rem;
    padding-bottom: 90px;                              /* Extra padding to prevent content being hidden under footer */
    overflow-x: hidden;
    overflow-y: auto;                                   /* Scrollable contents if viewport is shorter than content. */
    border-right: 1px solid rgb(221, 221, 221);

}

/* Media query for screens smaller than 768px (standard phone breakpoint) */
@media (max-width: 768px) {
    .sidebar-sticky {
        /* Add padding for mobile */
        padding-top: 5rem; 
    }
}

@supports ((position: -webkit-sticky) or (position: sticky)) {

    .sidebar-sticky {

        position: -webkit-sticky;
        position: sticky;

    }

}

li.nav-item a.nav-link {

    font-weight: 500;
    background: #F8F9FA;
    color: #606060;
    transition: 0.5s padding ease-out, 0.5s color ease-out, 0.5s background-color ease-out;

}

li.nav-item a.nav-link i {

    font-size: 1rem;
    padding-right: 0;
    transition: 0.3s transform ease-out;
    display: inline-block;
    transform: scale(1);

}

li.nav-item a.nav-link:hover {

    color: #2e82d1;
    padding-left: 2rem;
    transition: 0.15s padding ease-out, 0.15s color ease-out, 0.15s background-color ease-out;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;

}

li.nav-item a.nav-link:hover i {

    /* Keep the icon enlargement, but do not add extra width to the nav item on hover. */
    padding-right: 0;
    transform: scale(1.2);
    transition: 0.15s transform ease-out;

}

li.nav-item a.nav-link.active {
    
    background: #5d6aa0;
    color: #ffffff;
    
}

li.nav-item a.nav-link.active:hover {
    
    background: #2e82d1;
    
}

li.nav-item.nav-link .feather {

    margin-right: 4px;

}

.sidebar-heading {

    text-transform: uppercase;

}

.nav-submenu {

    padding-left: 1rem;
    background: #5d6aa0;
    font-size: 0.9rem;
    transition: background-color 0.15s ease-in-out;

}

.nav-item:hover > .collapse .nav-submenu {

    background-color: #2e82d1;

}

.nav-item-parent:hover > .nav-link:not(:hover) {

    padding-left: 2rem;
    background-color: #2e82d1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;

}

.nav-item-parent:hover > .nav-link:not(:hover) i {

    padding-right: .2rem;
    transform: scale(1.2);
    transition: 0.15s transform ease-out;

}

.nav-caret {

    transition: transform 0.2s ease;
    font-size: 0.75rem;

}

.nav-link[aria-expanded="true"] .nav-caret {

    transform: rotate(180deg);

}

/*-----------------------------------------------------*/

/* Tab-specific navigation styling */

.nav-tabs .nav-item .nav-link {

    padding-left: 1rem;
    border-radius: 0;
    border: 0;
    transition: margin-bottom 0s;
    background: #ececec;    

}

.nav-tabs .nav-item .nav-link:hover {

    padding-left: 1rem;
    padding-bottom: 1.5rem;
    margin-bottom: -1.5rem;
    background-color: #2e82d1;
    color: white;

}

/*-----------------------------------------------------*/

/* Alert Styling */

.alert {

    border-radius: 0;
    border-left-width: 1rem;
    border

}

.jumbotron .alert {

    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, .15);

}

.alert p:last-of-type {

    margin-bottom: 0;

}

/*-----------------------------------------------------*/

/* Toggle switch styling */
.switch {

    position: relative;
    display: inline-block;
    width: 2rem;
    height: 1.2rem;
    margin-top: 0.5rem;

}

/* Hide default HTML checkbox */
.switch input {

    opacity: 0;
    width: 0;
    height: 0;

}

/* The slider */
.slider {

    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ccc;
    -webkit-transition: .4s;
    transition: .4s;

}

.slider:before {

    position: absolute;
    content: "";
    height: 0.8rem;
    width: 0.8rem;
    left: 0.2rem;
    top: 0.2rem;
    background-color: white;
    -webkit-transition: .4s;
    transition: .4s;

}

input:checked + .slider {

    background-color: #2196F3;

}

input:focus + .slider {

    box-shadow: 0 0 1px #2196F3;

}

input:checked + .slider:before {

    -webkit-transform: translateX(0.9rem);
    -ms-transform: translateX(0.9rem);
    transform: translateX(0.9rem);

}

/*-----------------------------------------------------*/

/* Printer Cards Container */

.cartridge-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;          /* Aligns the wrapper content to the bottom */
    height: 100%;
}

.progress-vertical {

    width: 30px;                        /* Width of the vertical bar */
    min-height: 0px;                    /* To make it visible even at 0% */
    border-radius: 0.25rem;
    transition: height 0.6s ease;
    position: relative;                 /* Important for positioning the text */
    display: flex;
    justify-content: center;
    align-items: flex-end;

}

.progress-text {

    position: absolute;
    top: -20px; /* Position it above the bar */
    font-size: 0.8rem;
    font-weight: bold;
    white-space: nowrap;

}

/*-----------------------------------------------------*/

/* Flash Highlight Effect for Form Fields */
/* Defined in General.js and called in specific page JS where necessary */
.flash-highlight {
    
    background-color: #99ffa2; 
    border: 1px solid #66ff66;
    transition: background-color 0.5s ease;

}

/* Define the state after the highlight effect */
.form-control {

    transition: background-color 0.5s ease;

}

/*-----------------------------------------------------*/

/* Pagination styling */

/* This is the main pagination container - margin corrections to position between table and outer container border */
ul.pagination {

    margin-top: 0.25rem;
    margin-bottom: 0;

}

/*-----------------------------------------------------*/

/* Table styling for long entries */
.long-entry-cell {
    
    word-break: break-all; 
    word-wrap: break-word; 
    min-width: 1px; 

}

.long-entry-cell pre {
    
    white-space: pre-wrap !important; 
    word-break: break-all !important; 
    
}

/*-----------------------------------------------------*/

/* 2-column grid layout */
.two-col-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.5rem;
    align-items: start;
}

@media (max-width: 768px) {
    .two-col-grid {
        grid-template-columns: 1fr;
    }
}

/*-----------------------------------------------------*/

/* Timeline styling */
.timeline {
    border-left: 3px solid #c9ecef;         /* The vertical line */
    padding: 0 0 0 1.5rem;                    /* Padding to the right of the line */
    margin: 0;
    list-style: none;                         /* Remove default bullet points */
}

.timeline-item {
    position: relative;
}

/* Dot on timeline vertical line */
.timeline-item::before {
    content: '';
    position: absolute;
    left: -1.6rem;                            /* Position the circle to the left of the line */
    margin-left: -0.5rem;                     /* Centre the circle horizontally with respect to the line */
    top: 1rem;                              /* Centre the circle vertically with respect to the item */
    width: 1rem;                              /* Circle size */
    height: 1rem;                             /* Circle size */
    background-color: #007bff;              /* Circle color */
    border: 2px solid #ffffff;              /* Circle border */
    border-radius: 50%;                       
    z-index: 1;                               /* Ensure the circle is above the line */
}

.timeline-item:hover::before {
    background-color: #0056b3;
    transform: scale(1.5);
    transition: all 0.3s ease-in-out;
}

ul li.timeline-item .card:hover {
    background-color: #f8f9fa;
    transition: background-color 0.3s ease-in-out;
    cursor: pointer;
}

ul li.timeline-item .card .card-header {
    transition: background-color 0.3s ease-in-out;
}

ul li.timeline-item .card:hover .card-header {
    background: black;
    transition: background-color 0.3s ease-in-out;
}
/* 1. Base state targeting the specific card class */
ul li.timeline-item .card .card-header {
    transition: background-color 0.3s ease-in-out;
}

/* 2. Hover state targeting the header inside that card */
ul li.timeline-item .card:hover .card-header {
    background-color: rgb(228, 226, 226) !important; 
}
/*-----------------------------------------------------*/

/* ---------- */
/* ANIMATIONS */
/*------------*/

/* Wobble animation for attention-grabbing elements */

@keyframes wobble-fail {
  0%   { transform: rotate(0deg); }
  15%  { transform: rotate(-18deg); }
  30%  { transform: rotate(16deg); }
  45%  { transform: rotate(-12deg); }
  60%  { transform: rotate(10deg); }
  75%  { transform: rotate(-6deg); }
  90%  { transform: rotate(4deg); }
  100% { transform: rotate(0deg); }
}
@keyframes wobble-success {
  0%   { transform: translateY(0); }
  20%  { transform: translateY(-10px); }
  40%  { transform: translateY(0); }
  60%  { transform: translateY(-6px); }
  80%  { transform: translateY(0); }
  100% { transform: translateY(0); }
}
.wobble-fail    { animation: wobble-fail    0.5s ease-in-out; }
.wobble-success { animation: wobble-success 0.5s ease-in-out; }

/* Stretch animation for attention-grabbing elements */
@keyframes wobble-stretch {
  0%   { transform: scaleX(1); }
  25%  { transform: scaleX(2); }
  50%  { transform: scaleX(0.75); }
  75%  { transform: scaleX(1.25); }
  100% { transform: scaleX(1); }
}
.wobble-stretch { animation: wobble-stretch 1s ease-in-out; }

/* Growth animation for attention-grabbing elements */
@keyframes wobble-grow {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.4); }
  70%  { transform: scale(0.9); }
  100% { transform: scale(1); }
}
.wobble-grow { animation: wobble-grow 0.4s ease-in-out; }

/*-----------------------------------------------------*/

/* Document / Image preview (View Document modals) */

.document-preview-image-wrapper {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: auto;
}

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

/*-----------------------------------------------------*/

/* Permission checklist (API Tokens create/edit modals) */

.permission-checklist {
    max-height: 260px;
    overflow-y: auto;
}

.permission-checklist .permission-checklist-category {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #6c757d;
    margin: 0.75rem 0 0.25rem;
}

.permission-checklist .permission-checklist-category:first-child {
    margin-top: 0;
}

.permission-checklist .form-check {
    margin-bottom: 0.25rem;
}

/*-----------------------------------------------------*/

/* Manage Colours page */

.colour-palette-wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.colour-palette-swatch {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 120px;
    height: 60px;
    padding: 0.5rem 1rem;
    border-radius: 0.375rem;
    font-weight: 600;
    text-align: center;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
    word-break: break-word;
}

.colour-table-swatch {
    display: inline-block;
    padding: 0.25rem 0.6rem;
    border-radius: 0.25rem;
    font-family: monospace;
    font-weight: 600;
}

.colour-picker-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: calc(1.5em + 0.75rem + 2px);
    box-sizing: border-box;
    padding: 0;
    border: 1px solid #ced4da;
    border-right: none;
    border-radius: 0.25rem 0 0 0.25rem;
    background: #fff;
    overflow: hidden;
}

.colour-swatch-input {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    cursor: pointer;
}

.colour-swatch-input::-webkit-color-swatch-wrapper {
    padding: 0;
}

.colour-swatch-input::-webkit-color-swatch {
    border: none;
}

.colour-swatch-input::-moz-color-swatch {
    border: none;
}

.colour-preview-box {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 180px;
    min-height: 42px;
    padding: 0.5rem 1rem;
    border-radius: 0.375rem;
    font-weight: 600;
    border: 1px solid rgba(0,0,0,0.15);
}

/*-----------------------------------------------------*/

/* Job Homepage - Position Palettes card */

.position-palette-wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.position-palette-swatch {
    display: flex;
    flex-direction: column;
    width: 130px;
    padding: 0;
    border: 0;
    border-radius: 0.375rem;
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
    background: none;
    text-align: left;
}

.position-palette-swatch.is-clickable {
    cursor: pointer;
}

.position-palette-swatch.is-clickable:hover,
.position-palette-swatch.is-clickable:focus {
    box-shadow: 0 2px 6px rgba(0,0,0,0.35);
    outline: none;
}

.position-palette-swatch.is-removed {
    opacity: 0.45;
}

.position-palette-swatch-stripes {
    display: flex;
    height: 44px;
}

.position-palette-swatch-stripes > span {
    flex: 1 1 0;
}

.position-palette-swatch-label {
    padding: 0.35rem 0.5rem;
    font-weight: 600;
    font-size: 0.85rem;
    text-align: center;
    word-break: break-word;
    background: #fff;
    color: #212529;
}

/*-----------------------------------------------------*/

/* Checklist of colours shown in the Assign Colours (palette membership) modal */
.colour-assign-checklist {
    max-height: 360px;
    overflow-y: auto;
    padding-right: 0.25rem;
}

.colour-assign-checklist .colour-assign-item {
    position: relative;
    height: 100%;
    padding: 0.5rem 0.75rem 0.5rem 1.5rem;
    border: 1px solid #dee2e6;
    border-radius: 0.375rem;
    background-color: #fff;
    transition: border-color 0.15s ease-in-out, background-color 0.15s ease-in-out;
}

.colour-assign-checklist .colour-assign-item:hover {
    border-color: #adb5bd;
}

.colour-assign-checklist .colour-assign-item.selected {
    border-color: #86b7fe;
    background-color: #eef6ff;
}

.colour-assign-checklist .custom-control-label {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 1.25rem;
    padding-left: 0.25rem;
    cursor: pointer;
    overflow: hidden;
}

.colour-assign-checklist .custom-control-label span:last-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.colour-assign-checklist .colour-assign-swatch {
    display: inline-block;
    width: 14px;
    height: 14px;
    flex: 0 0 auto;
    border-radius: 0.2rem;
    margin-right: 0.4rem;
    border: 1px solid rgba(0,0,0,0.15);
}

.drag-handle {
    cursor: grab;
    color: #adb5bd;
}

.js-staff-row.dragging,
.js-crew-row.dragging {
    opacity: 0.4;
}

.row-drop-flash {
    animation: Row_Drop_Flash 1s ease-out;
}

@keyframes Row_Drop_Flash {
    0% { background-color: #fff3cd; }
    100% { background-color: transparent; }
}

/* Feedback module - rating histogram (Manage_Feedback.js) */
.rating-histogram-bars {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    height: 160px;
    padding-top: 1.25rem;
}

.rating-histogram-column {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    flex: 1 1 0;
    height: 100%;
}

.rating-histogram-value {
    font-size: 0.75rem;
    font-weight: 600;
    margin-bottom: 0.25rem;
}

.rating-histogram-bar {
    width: 100%;
    max-width: 24px;
    border-radius: 4px 4px 0 0;
}

.rating-histogram-label {
    font-size: 0.75rem;
    margin-top: 0.35rem;
}

/*-----------------------------------------------------*/

/* Document drop zone / pending upload list - shared by every page that uploads documents via drag-and-drop
   (Manage_Documents.php, Job.php, Rigging_Documents.php) */

.document-drop-zone {
    border: 2px dashed #ccc;
    border-radius: 0.5rem;
    padding: 2.5rem 1rem;
    text-align: center;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.document-drop-zone:hover {
    background-color: #f8f9fa;
}

.document-drop-zone.drag-over {
    background-color: #eef6ff;
    border-color: #007bff;
}

.document-drop-zone.drop-zone-disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/*-----------------------------------------------------*/

/* Extra-wide modal size - Bootstrap only ships up to modal-xl (1140px); pass Size "xxl" to Generate_Modal() for this one */

@media (min-width: 1200px) {
    .modal-xxl {
        max-width: 95vw;
    }
}

/* MVR Rig Details modal - Fixtures/Truss/Layers tables independently scroll past this height instead of growing the modal off the bottom of the screen (Job.php / Job_MVR.js) */

.MVR_Rig_Table_Scroll {
    max-height: 45vh;
    overflow-y: auto;
}

/* MVR Rig Details modal - Fixture ID / patch conflicts table - some files have hundreds of clashes, so it scrolls (header pinned) rather than pushing the rig breakdown out of view (Job.php / Job_MVR.js) */

.MVR_Rig_Conflicts_Scroll {
    max-height: 30vh;
    overflow-y: auto;
}

.MVR_Rig_Conflicts_Scroll thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background-color: #fff;
}

/* MVR Rig Details modal - Layers table colour swatch (Job.php / Job_MVR.js) */

.MVR_Layer_Colour_Swatch {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 2px;
    margin-right: 8px;
    vertical-align: middle;
    border: 1px solid rgba(0, 0, 0, .15);
}

.document-pending-row {
    border: 1px solid #e2e2e2;
    border-radius: 0.375rem;
    padding: 0.75rem;
    margin-bottom: 0.75rem;
}

/*-----------------------------------------------------*/

/* Rigging Certificates page */

.rigging-pattern-row {
    border: 1px solid #e2e2e2;
    border-radius: 0.375rem;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.5rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/*-----------------------------------------------------*/

/* Utilities */

.cursor-pointer {
    cursor: pointer;
}
/*-----------------------------------------------------*/

/* Job PAL logo - top right of the Job Homepage, admin Manage Job page and label spreadsheets (continuity with Portal v1) */

.job-pal-logo {
    display: block;
    max-height: 60px;
    max-width: 260px;
    width: auto;
    height: auto;
    object-fit: contain;
}

@media (max-width: 767.98px) {
    .job-pal-logo {
        max-height: 40px;
        max-width: 160px;
    }
}

/*-----------------------------------------------------*/

/* Job navigation bar (assets/partials/Job_Top_Navigation.php) - under the header of every job page. Its own classes,
   not .nav-item/.nav-link, so the sidebar's li.nav-item a.nav-link and .nav-tabs hover rules above can't reach it.
   Wraps rather than scrolling sideways on a phone - a scrolling strip would clip the Labels/Generate PDF menus */

.job-nav {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    border-bottom: 1px solid #dee2e6;
}

.job-nav-list {
    display: flex;
    flex-wrap: wrap;
    list-style: none;
    margin: 0;
    padding: 0;
}

.job-nav-link {
    display: block;
    padding: 0.6rem 1rem;
    margin-bottom: -1px;
    border-bottom: 3px solid transparent;
    color: #606060;
    font-weight: 500;
    white-space: nowrap;
    transition: color 0.15s ease-out, border-color 0.15s ease-out;
}

.job-nav-link:hover,
.job-nav-link:focus,
.job-nav-item.show > .job-nav-link {
    color: #2e82d1;
    border-bottom-color: #b9d6f1;
    text-decoration: none;
}

.job-nav-link.active,
.job-nav-link.active:hover,
.job-nav-link.active:focus {
    color: #2e82d1;
    border-bottom-color: #2e82d1;
    font-weight: 700;
}

.job-nav-link i {
    margin-right: 0.25rem;
}

/* Labels can run to a few dozen entries on a job with several subgroups. The toggles set data-flip="false" - flipped
   above the bar, a tall menu would slide under the fixed top bar */
.job-nav-menu {
    max-height: 70vh;
    overflow-y: auto;
}

.job-nav-menu-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
}

/* Palettes dropdown - the Job Homepage's position swatches, colours passed in as --palette-colour */
.job-nav-palettes {
    width: 460px;
    max-width: calc(100vw - 1rem);
    padding: 0.75rem;
}

.job-nav-palettes .position-palette-swatch-stripes > span {
    background-color: var(--palette-colour);
}

.job-nav-menu-badges .badge + .badge {
    margin-left: 0.25rem;
}

.job-nav-menu .dropdown-header {
    padding-top: 0.5rem;
    font-size: 1rem;
}

@media (max-width: 575.98px) {
    .job-nav-link {
        padding: 0.5rem 0.75rem;
    }

    .job-nav-menu {
        max-height: 55vh;
    }
}

/*-----------------------------------------------------*/

/* Job Homepage - Subgroups card: striped rows (same shade as Bootstrap's .table-striped) so each subgroup reads as its own item */

.job-subgroup-list .list-group-item:nth-child(odd) {
    background-color: rgba(0, 0, 0, 0.05);
}

.job-subgroup-list .list-group-item:hover {
    background-color: rgba(0, 0, 0, 0.075);
}

/*-----------------------------------------------------*/

/* Job Pull Lists (pages/job-Pull_List.php) - live Hiretrack EQ lists */

/* Lists only LCR staff can see (below heavy pencil) are dimmed so they stand apart from what crew see */
.pull-list-unapproved td {
    opacity: 0.65;
}

.pull-list-progress {
    min-width: 90px;
    height: 1.1rem;
}

/* Single list header - Prep/Out/Back dates on the left, progress on the right of the same line (it drops under the
   dates on narrow screens) */
.pull-list-header-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1.5rem;
}

.pull-list-header-progress {
    flex: 0 1 320px;
}

.pull-list-header-progress .pull-list-progress {
    margin-bottom: 0.25rem;
}

.pull-list-dates {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.5rem;
}

.pull-list-search {
    max-width: 280px;
}

.pull-list-section + .pull-list-section {
    margin-top: 1.5rem;
}

.pull-list-section-title {
    margin-bottom: 0.5rem;
}

/* Every section is its own table - a fixed layout with set widths keeps their columns aligned down the page. Item
   takes whatever's left; the min-width stops it being squeezed away on a phone (.table-responsive scrolls instead) */
.pull-list-table {
    table-layout: fixed;
    min-width: 42.5rem;
}

/* A little taller than .table-sm's 0.3rem - easier to read and tap on a smaller screen */
.pull-list-table td {
    overflow-wrap: break-word;
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

.pull-list-seen-col {
    width: 2.5rem;
}

.pull-list-type-col {
    width: 3.5rem;
}

/* "Seen" tick - the label takes over the cell's padding so the whole cell can be tapped, not just the box */
.pull-list-table td.pull-list-seen-cell {
    padding: 0;
}

.pull-list-seen-label {
    display: block;
    margin: 0;
    padding: 0.5rem 0.3rem;
    text-align: center;
    cursor: pointer;
}

.pull-list-seen {
    width: 1.15rem;
    height: 1.15rem;
    vertical-align: middle;
    cursor: pointer;
    accent-color: #28a745;
}

/* A line the user has ticked off. Badges and buttons are inline-blocks, so the line-through skips them */
.pull-list-seen-row td {
    text-decoration: line-through;
    color: #6c757d;
}

.pull-list-seen-changed {
    color: #856404;
    font-size: 0.85rem;
    font-style: normal;
}

/* Wide enough for the longest heading ("Dispatch"/"Check-in") */
.pull-list-qty-col {
    width: 5.5rem;
}

/* Record type badge (N, C, CC, R...) - one colour per family, matching Portal v1's row colouring */
.pull-list-type {
    display: inline-block;
    min-width: 2rem;
    padding: 0.1rem 0.3rem;
    border-radius: 0.25rem;
    font-size: 0.8rem;
    font-weight: 700;
    text-align: center;
    background-color: #e9ecef;
    color: #495057;
}

/* Kept separate (and more specific) so it beats Bootstrap's dotted abbr[title] underline without also outranking
   the per-type colours below */
abbr.pull-list-type[title] {
    text-decoration: none;
    cursor: help;
}

.pull-list-type-n  { background-color: #d4edda; color: #155724; }
.pull-list-type-c  { background-color: #cce5ff; color: #004085; }
.pull-list-type-cc { background-color: #e7f1ff; color: #004085; }
.pull-list-type-r,
.pull-list-type-cr { background-color: #fff3cd; color: #856404; }
.pull-list-type-a,
.pull-list-type-ca,
.pull-list-type-p  { background-color: #e2d9f3; color: #432874; }
.pull-list-type-f  { background-color: #f8f9fa; color: #6c757d; border: 1px solid #dee2e6; }

.pull-list-line-actions {
    float: right;
    display: inline-flex;
    gap: 0.25rem;
    margin-left: 0.5rem;
}

.pull-list-sub-hire {
    color: #c0392b;
    font-size: 0.9rem;
}

/* Component rows get a faint tint - except their amber/green prep cells, which must still show */
.pull-list-child td:not(.table-success):not(.table-warning) {
    background-color: rgba(0, 0, 0, 0.025);
}

.pull-list-child-name {
    padding-left: 2rem !important;
    font-style: italic;
}

.pull-list-notes {
    white-space: pre-line;
}

/*-----------------------------------------------------*/

/* Offline mode (assets/js/Offline_Mode.js) - the job label spreadsheets and Equipment Requests */

/* A row holding a change made offline that hasn't been uploaded yet - on its first visible cell */
td.spreadsheet-row-offline-marker {
    box-shadow: inset 4px 0 0 #f0ad4e;
}

/* The upload review's list of changes */
.offline-upload-new-rows {
    max-height: 240px;
    overflow-y: auto;
}

/*-----------------------------------------------------*/

/* Job label spreadsheet - fixture lists (pages/Job_Labels.php, Job_Labels.js fixture mode) */

/* A value from the MVR that doesn't fit the row's label (too long, or not allowed there) - marked, never blocked */
td.label-fixture-cell-warning {
    box-shadow: inset 0 -3px 0 #f0ad4e;
    cursor: help;
}

/* The read-only Label column - readable despite jspreadsheet fading read-only cells, cut short with an ellipsis */
#Label_Grid td.label-fixture-label-cell {
    color: #495057;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Manage Label Types - the Inventory Links modal's note under the picker */
.label-inventory-links-note {
    margin-top: 0.75rem;
}

/*-----------------------------------------------------*/

/* MVR Inventory Map's Local Names tab (pages/admin/MVR_Inventory_Map.php) */

.mvr-local-names-search {
    max-width: 400px;
}

/*-----------------------------------------------------*/

/* Job Equipment Requests (pages/job-Equipment_Order.php) and its Equipment Request Items admin page */

/* Toolbar and legend above the grid */
.equipment-toolbar {
    gap: 0.5rem;
}

.equipment-search {
    max-width: 320px;
}

.equipment-legend {
    gap: 1rem;
}

.equipment-legend-swatch {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    border: 1px solid #ccc;
    vertical-align: text-bottom;
}

/* Grid cells - jspreadsheet greys out every readonly cell, which would leave view-only crew squinting at the quantities */
#Equipment_Grid .jss_worksheet td {
    white-space: nowrap;
}

#Equipment_Grid .jss_worksheet > tbody > tr > td.readonly {
    color: #212529;
}

#Equipment_Grid .jss_worksheet > tbody > tr > td.equipment-item-cell {
    overflow: hidden;
    text-overflow: ellipsis;
}

#Equipment_Grid .jss_worksheet > tbody > tr > td.equipment-item-inactive {
    color: #888;
    font-style: italic;
}

#Equipment_Grid .jss_worksheet > tbody > tr > td.equipment-info-cell {
    color: #6c757d;
    background-color: #f8f9fa;
}

#Equipment_Grid .jss_worksheet > tbody > tr > td.equipment-total-cell {
    font-weight: bold;
    background-color: #f1f3f5;
}

/* Category break rows - in the grid, and in a version's change tables */
#Equipment_Grid .jss_worksheet > tbody > tr > td.equipment-category-row,
.equipment-category-heading > td {
    background-color: #1a225d !important;
    color: #fff !important;
    text-transform: uppercase;
    font-size: 1.1rem;
    text-align: left;
    cursor: default;
    font-family: 'Bebas Neue', sans-serif;
}

/* A cell against the last version sent - shared with the legend */
.equipment-state-requested { background-color: #d4edda !important; }
.equipment-state-increased { background-color: #fff3cd !important; }
.equipment-state-reduced   { background-color: #f8d7da !important; }

/* The selected row, and everyone else's selected cell - each person's colour comes from --presence-colour, which
   Job_Equipment_Order.js sets on the cell */
#Equipment_Grid tr.spreadsheet-row-selected > td {
    background-color: #eef4ff;
}

#Equipment_Grid td.spreadsheet-presence-active {
    position: relative;
    outline: 2px solid var(--presence-colour, #999);
    outline-offset: -2px;
}

#Equipment_Grid .spreadsheet-presence-badge {
    position: absolute;
    top: 1px;
    right: 1px;
    font-size: 0.7rem;
    line-height: 1;
    font-family: sans-serif;
    color: #fff;
    background-color: var(--presence-colour, #999);
    padding: 0.2rem;
    pointer-events: none;
    z-index: 5;
    white-space: nowrap;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}

/* Fullscreen - the grid and its toolbar cover the window, as Portal v1's did, and the page behind stops scrolling */
#Equipment_Workspace.equipment-fullscreen {
    position: fixed;
    inset: 0;
    z-index: 1040;
    background: #fff;
    padding: 0.75rem;
    overflow: hidden;
}

body.equipment-fullscreen-open {
    overflow: hidden;
}

/* Columns modal */
#Equipment_Location_List .list-group-item {
    cursor: grab;
}

#Equipment_Location_List .list-group-item.dragging {
    opacity: 0.5;
}

/* Change tables and version notes */
.equipment-change-positive {
    color: #1e7e34;
    font-weight: bold;
}

.equipment-change-negative {
    color: #c82333;
    font-weight: bold;
}

.equipment-version-notes {
    white-space: pre-wrap;
    max-width: 320px;
}

.equipment-notes-quote {
    white-space: pre-wrap;
}

/* Equipment Request Items admin page (pages/admin/Manage_Equipment_Order_Items.php) */
.equipment-items-toolbar {
    gap: 0.5rem;
}

.equipment-items-filter-list {
    max-width: 220px;
}

.equipment-items-filter-status {
    max-width: 160px;
}

.equipment-items-search {
    max-width: 280px;
}

.equipment-items-select-column {
    width: 2rem;
}

.equipment-items-list-picker {
    min-width: 180px;
}

.equipment-items-add-results {
    max-height: 50vh;
    overflow-y: auto;
}

/*-----------------------------------------------------*/
/* PDF Templates (pages/admin/Manage_PDF_Templates.php) and the PDF Template Editor (pages/admin/PDF_Template_Editor.php) */

.pdf-templates-search {
    max-width: 400px;
}

/* Editor layout - the tabs on the left, the live preview on the right (stacked on narrower screens) */
.pdf-editor {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(360px, 42%);
    gap: 1rem;
    align-items: start;
}

@media (max-width: 1199.98px) {
    .pdf-editor {
        grid-template-columns: minmax(0, 1fr);
    }
}

.pdf-editor-main {
    min-width: 0;
}

.pdf-editor-tab-content {
    padding-top: 1rem;
}

.pdf-editor-split {
    display: grid;
    grid-template-columns: minmax(260px, 38%) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

@media (max-width: 991.98px) {
    .pdf-editor-split {
        grid-template-columns: minmax(0, 1fr);
    }
}

.pdf-editor-list-card .card-body {
    max-height: 70vh;
    overflow-y: auto;
}

.pdf-editor-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    padding: 0.5rem;
}

.pdf-editor-add-menu {
    max-height: 70vh;
    overflow-y: auto;
}

/* Preview - stays in view while the tabs scroll */
.pdf-editor-preview {
    position: sticky;
    top: 1rem;
}

.pdf-editor-preview-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem;
}

.pdf-editor-preview-job {
    flex: 1 1 200px;
    min-width: 0;
}

.pdf-editor-preview-status {
    padding: 0.4rem 1rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.125);
}

.pdf-editor-preview-warnings {
    padding: 0.4rem 1rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.125);
    font-size: 85%;
    max-height: 30vh;
    overflow-y: auto;
}

.pdf-editor-preview-frame-wrap {
    position: relative;
    height: calc(100vh - 13rem);
    min-height: 480px;
}

.pdf-editor-preview-frame {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
    background: #525659;
}

.pdf-editor-preview-busy {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.7);
}

/* Block tree - indented by --depth, set per row */
.pdf-tree {
    user-select: none;
    outline: none;
}

.pdf-tree-row {
    display: flex;
    align-items: center;
    padding: 0.3rem 0.5rem 0.3rem calc(0.5rem + var(--depth, 0) * 1.1rem);
    border-bottom: 1px solid #f0f0f0;
    cursor: pointer;
    font-size: 0.9rem;
    white-space: nowrap;
    overflow: hidden;
}

.pdf-tree-row:hover {
    background: #f5f8ff;
}

.pdf-tree-row.selected {
    background: #e0ebff;
    box-shadow: inset 3px 0 0 #1a3e9a;
}

.pdf-tree-row.dragging {
    opacity: 0.4;
}

.pdf-tree-row.drop-before {
    box-shadow: inset 0 2px 0 #28a745;
}

.pdf-tree-row.drop-after {
    box-shadow: inset 0 -2px 0 #28a745;
}

.pdf-tree-row.drop-inside {
    background: #d4edda;
}

.pdf-tree-column {
    background: #fafafa;
    font-style: italic;
}

.pdf-tree-toggle {
    flex: 0 0 1rem;
    width: 1rem;
    color: #6c757d;
}

.pdf-tree-icon {
    margin-right: 0.35rem;
    color: #1a225d;
}

.pdf-tree-type {
    margin-right: 0.4rem;
    font-weight: bold;
}

.pdf-tree-summary {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #6c757d;
}

.pdf-tree-badges .badge {
    margin-left: 0.2rem;
}

.pdf-tree-empty {
    padding: 0.25rem 0.5rem 0.25rem calc(1.5rem + var(--depth, 0) * 1.1rem);
    border-bottom: 1px solid #f0f0f0;
    color: #adb5bd;
    font-size: 0.8rem;
    font-style: italic;
}

/* Property forms */
.pdf-editor-form-heading {
    margin-top: 1.25rem;
    padding-top: 0.75rem;
    border-top: 1px solid #dee2e6;
}

.pdf-editor-form-heading:first-child {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

/* The selected row of a list keeps its buttons readable on the blue */
.list-group-item.active .pdf-editor-list-buttons .btn {
    background: #ffffff;
}

.pdf-editor-style-box {
    margin-bottom: 0.5rem;
    padding-left: 0.75rem;
    border-left: 3px solid #e0ebff;
}

.pdf-editor-colour input[type="color"] {
    width: 3rem;
    padding: 0.1rem;
}

.pdf-editor-refine-row select {
    width: auto;
}

.pdf-editor-refine-row input[list] {
    max-width: 12rem;
}

.pdf-editor-direction {
    max-width: 6.5rem;
}

.pdf-editor-limit {
    max-width: 6rem;
}

.pdf-editor-list-buttons .btn {
    padding: 0.1rem 0.35rem;
}

.pdf-editor-columns-table td {
    vertical-align: top;
}

.pdf-editor-columns-table .form-group {
    margin-bottom: 0;
}

.pdf-editor-col-width {
    width: 5.5rem;
}

.pdf-editor-col-align {
    width: 6.5rem;
}

.pdf-editor-colour-rules,
.pdf-editor-column-options {
    background: #f8f9fa;
}

.pdf-editor-columns-table .pdf-editor-column-options .form-group {
    margin-bottom: 0.5rem;
}

.pdf-editor-detail-line {
    margin-bottom: 0.5rem;
    border-bottom: 1px dashed #dee2e6;
}

.pdf-editor-thumbnail {
    max-width: 5rem;
    max-height: 3rem;
    border: 1px solid #dee2e6;
    background: repeating-conic-gradient(#eeeeee 0 25%, #ffffff 0 50%) 50% / 10px 10px;
}

.pdf-editor-image-case-value {
    width: 40%;
}

.pdf-editor-column-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.pdf-editor-column-chip {
    padding: 0.1rem 0.4rem;
    border: 1px solid #dee2e6;
    border-radius: 0.25rem;
    background: #f8f9fa;
    font-size: 0.8rem;
}

.pdf-editor-static-column {
    width: 12rem;
}

.pdf-editor-static-scroll {
    max-height: 50vh;
    overflow: auto;
}

.pdf-editor-versions {
    max-height: 60vh;
    overflow-y: auto;
}

.pdf-editor-source-test {
    max-height: 65vh;
    overflow: auto;
}

/* Page design and cover elements - a map of the page beside the element list */
.pdf-editor-elements-layout {
    display: grid;
    grid-template-columns: minmax(180px, 34%) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

.pdf-editor-page-map {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid #ced4da;
    background: #ffffff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
}

.pdf-map-page {
    fill: #ffffff;
}

.pdf-map-content {
    fill: none;
    stroke: #1a3e9a;
    stroke-width: 0.4;
    stroke-dasharray: 2 2;
}

.pdf-map-element {
    cursor: pointer;
}

.pdf-map-element.selected {
    cursor: move;
}

.pdf-map-outline {
    fill: none;
    stroke: transparent;
    stroke-width: 0.5;
}

.pdf-map-element:hover .pdf-map-outline {
    stroke: #17a2b8;
}

.pdf-map-element.selected .pdf-map-outline {
    stroke: #e83e8c;
    stroke-width: 0.8;
    stroke-dasharray: 2 1;
}

.pdf-map-image {
    fill: #d4edda;
    stroke: #28a745;
    stroke-width: 0.3;
}

.pdf-map-hit {
    stroke: transparent;
    stroke-width: 4;
}

.pdf-editor-element-list {
    max-height: 16rem;
    overflow-y: auto;
    border: 1px solid rgba(0, 0, 0, 0.125);
}

/* Placeholder picker - positioned beside the field it was opened from */
.pdf-editor-picker {
    position: absolute;
    z-index: 1070;
    width: 26rem;
    max-width: calc(100vw - 1rem);
}

.pdf-editor-picker-body {
    max-height: 20rem;
    overflow-y: auto;
}

.pdf-editor-picker-format {
    max-width: 8rem;
}

.pdf-picker-group {
    padding: 0.35rem 0.75rem 0.15rem;
    background: #f8f9fa;
    color: #6c757d;
    font-size: 0.75rem;
    font-weight: bold;
    text-transform: uppercase;
}

.pdf-picker-item {
    display: block;
    width: 100%;
    padding: 0.2rem 0.75rem;
    border: 0;
    background: none;
    font-size: 0.85rem;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pdf-picker-item:hover,
.pdf-picker-item:focus {
    background: #e0ebff;
}

/*-----------------------------------------------------*/

/* Job Network page (pages/job-Network.php) and Network Device Models admin page */

.network-table td {
    vertical-align: middle;
}

.network-table .network-col-number {
    width: 5.5rem;
}

.network-table .network-col-port {
    width: 3.5rem;
    font-weight: bold;
}

/* A VLAN/trunk colour - the colour itself is set inline as --network-swatch (it's the job's data) */
.network-swatch {
    display: inline-block;
    flex-shrink: 0;
    width: 1.1rem;
    height: 1.1rem;
    border: 1px solid rgba(0, 0, 0, 0.25);
    border-radius: 0.2rem;
    background: var(--network-swatch, transparent);
    vertical-align: middle;
}

.network-swatch-empty {
    background: repeating-linear-gradient(45deg, #ffffff, #ffffff 3px, #dddddd 3px, #dddddd 6px);
}

/* Racks & Devices - the rack/device cards tile across the page, each only as wide as its header and devices need (never
   wider than the page - its devices wrap instead). The card with a device open takes the full width for its settings */
.network-cards {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
}

.network-card {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 100%;
}

.network-card.network-card-open {
    flex-basis: 100%;
}

/* A card's device tiles - a fixed width each (room for a 16-port switch's port dots), wrapping */
.network-device-tiles {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.network-device-tile-slot {
    width: 17rem;
    max-width: 100%;
}

/* Padded, as a card sized to its header leaves the title's auto margin nothing to push the buttons away with */
.network-card-title {
    min-width: 16rem;
    padding-right: 0.75rem;
}

.network-label-name,
.network-composite-name {
    max-width: 22rem;
    font-weight: bold;
}

/* A composite rack's card - a section per label (its name, preview/print, device tiles), side by side as they fit */
.network-composite-members {
    display: flex;
    flex-wrap: wrap;
    gap: 0 1.25rem;
}

.network-composite-member {
    min-width: 0;
    max-width: 100%;
}

/* A device's small card on its rack's card - click to open its settings underneath */
.network-device-tile {
    cursor: pointer;
    transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.network-device-tile:hover,
.network-device-tile:focus {
    border-color: #2e82d1;
    outline: none;
}

.network-device-tile:focus {
    box-shadow: 0 0 0 0.2rem rgba(46, 130, 209, 0.25);
}

.network-device-tile.active {
    border-color: #2e82d1;
    background: #e0ebff;
}

.network-tile-title {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* One dot per Ethernet port in the port's colour (--network-swatch) - ringed when the port's on the label */
.network-tile-ports {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem;
}

.network-tile-port {
    display: inline-block;
    width: 0.7rem;
    height: 0.7rem;
    border: 1px solid rgba(0, 0, 0, 0.2);
    border-radius: 50%;
    background: var(--network-swatch, transparent);
    opacity: 0.45;
}

.network-tile-port.on-label {
    border-color: #343a40;
    opacity: 1;
}

/* The open device's settings, under its rack's small cards */
.network-device-detail {
    border-width: 2px;
}

.network-device-name {
    max-width: 16rem;
}

/* Ports that aren't on the label - still the device's, just not printed */
.network-port-unlabelled td {
    color: #6c757d;
}

.network-port-name {
    min-width: 7rem;
}

.network-port-member {
    min-width: 9rem;
}

.network-input-ip {
    min-width: 9rem;
}

/* A device's IP interfaces - a band above its ports, side by side as the card's width allows (auto-fill keeps a lone IP
   one column wide rather than stretching it across the card) */
.network-interface-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 24rem), 1fr));
    gap: 0.5rem;
    align-items: start;
}

.network-interface {
    padding: 0.5rem;
    border: 1px solid #dee2e6;
    border-radius: 0.25rem;
    background: #f8f9fa;
}

.network-interface-add {
    padding: 0.5rem 0;
}

/* A trunk's VLANs - one tick box per VLAN, edged in its colour */
.network-trunk-vlans {
    min-width: 18rem;
}

.network-vlan-chip {
    display: inline-flex;
    align-items: center;
    margin: 0 0.25rem 0.25rem 0;
    padding: 0.05rem 0.4rem 0.05rem 0.3rem;
    border: 1px solid #dee2e6;
    border-left: 0.35rem solid var(--network-swatch, #cccccc);
    border-radius: 0.25rem;
    background: #f8f9fa;
    font-size: 0.8rem;
    cursor: pointer;
}

.network-vlan-chip input {
    margin-right: 0.25rem;
}

.network-colour-select {
    min-width: 7.5rem;
}

.network-untagged-select {
    min-width: 11rem;
}

/* Process Engines tab - a template's inputs, one row each */
.network-pe-name {
    min-width: 10rem;
}

.network-pe-mode {
    min-width: 6.5rem;
}

.network-pe-inputs {
    min-width: 24rem;
}

.network-pe-input + .network-pe-input {
    margin-top: 0.25rem;
}

.network-pe-priority {
    width: 4.5rem;
}

/* Keeps the rows lined up where an input has no remove button */
.network-pe-spacer {
    display: inline-block;
    width: 0.75rem;
}

.network-pe-switch {
    min-width: 15rem;
}

.network-dmx-universe {
    min-width: 5rem;
}

/* A port's Connected To cell - the other end (and its VLAN/trunk underneath), or free text */
.network-connection {
    min-width: 9rem;
    overflow-wrap: anywhere;
}

/* Label Network Wiring page (pages/admin/Label_Network_Wiring.php) */

/* Measures the label's real mm size off-screen, so the preview can be scaled to fit */
.network-wiring-sizer {
    position: absolute;
    top: -9999px;
    left: -9999px;
    visibility: hidden;
}

.network-wiring-preview {
    position: relative;
    margin: 0 auto;
    overflow: hidden;
}

.network-wiring-frame {
    position: absolute;
    top: 0;
    left: 0;
    border: 0;
    overflow: hidden;
    transform-origin: top left;
}

.network-wiring-table select {
    min-width: 6rem;
}

.network-wiring-chips {
    min-width: 12rem;
}

/* One element that can take a role - ticked ones stand out */
.network-wiring-chip {
    display: inline-flex;
    align-items: center;
    margin: 0 0.25rem 0.25rem 0;
    padding: 0.05rem 0.4rem 0.05rem 0.3rem;
    border: 1px solid #dee2e6;
    border-radius: 0.25rem;
    background: #f8f9fa;
    font-size: 0.8rem;
    white-space: nowrap;
    cursor: pointer;
}

.network-wiring-chip input {
    margin-right: 0.25rem;
}

.network-wiring-chip.active {
    border-color: #2e82d1;
    background: #e0ebff;
}

.network-wiring-chip.disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.network-wiring-table select.network-wiring-device {
    min-width: 9rem;
}

.network-wiring-table th[scope="row"],
.network-wiring-table td {
    vertical-align: middle;
}

/* Its Default Port Setup card - one device's ports at a time, as they start on a job. A tab's model name is dimmed in
   the tab's own text colour, so it still reads on the active (filled) tab */
.network-default-tab-model {
    opacity: 0.75;
}

.network-default-name {
    min-width: 7rem;
}

.network-default-member {
    min-width: 9rem;
}

.network-default-connect {
    min-width: 10rem;
}

.network-default-connected-to {
    min-width: 8rem;
}


/* ----------------------------------------------------------------------------------------------------------------------
   Job Universe View (pages/job-Universes.php, assets/js/pages/Job_Universes.js) - a job's DMX patch as 512 channel grids
   --universe-colour / --universe-text / --universe-lane(s) / --universe-columns / --universe-percent are set at runtime
   ---------------------------------------------------------------------------------------------------------------------- */

.universe-stat-value {
    font-size: 1.8rem;
    font-weight: 700;
    line-height: 1.1;
}

.universe-stat-label {
    font-weight: 600;
}

.universe-stat-clash .universe-stat-value {
    color: #dc3545;
}

.universe-stat-ok .universe-stat-value {
    color: #198754;
}

.universe-swatch {
    display: inline-block;
    width: 0.9rem;
    height: 0.9rem;
    margin-right: 0.4rem;
    border-radius: 2px;
    vertical-align: -0.1rem;
    background: var(--universe-colour, #6c757d);
}

.universe-quantity-table td,
.universe-quantity-table th {
    vertical-align: middle;
}

/* Universe list - a column beside the grid on wide screens, a scrolling row above it on narrow ones */
.universe-list {
    display: flex;
    flex-direction: column;
    max-height: 70vh;
    overflow-y: auto;
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: 0.25rem;
}

.universe-list-item {
    flex: 0 0 auto;
    display: block;
    width: 100%;
    padding: 0.5rem 0.75rem;
    text-align: left;
    color: #495057;
    background: transparent;
    border: 0;
    border-left: 3px solid transparent;
    border-bottom: 1px solid #f1f3f5;
}

.universe-list-item:hover {
    background: #f8f9fa;
}

.universe-list-item.active {
    background: #e7f1ff;
    color: #0a58ca;
    border-left-color: #0d6efd;
    font-weight: 600;
}

.universe-list-title,
.universe-list-meta {
    display: block;
}

.universe-list-meta {
    font-size: 0.8rem;
    font-weight: 400;
    color: #868e96;
}

.universe-list-item.active .universe-list-meta {
    color: #0a58ca;
}

.universe-list-bar {
    display: block;
    height: 4px;
    margin-top: 0.3rem;
    background: #e9ecef;
    border-radius: 2px;
    overflow: hidden;
}

.universe-list-bar-fill {
    display: block;
    height: 100%;
    width: var(--universe-percent, 0%);
    background: #0d6efd;
}

@media (max-width: 991.98px) {

    .universe-list {
        flex-direction: row;
        max-height: none;
        overflow-x: auto;
        overflow-y: hidden;
    }

    .universe-list-item {
        width: auto;
        min-width: 8.5rem;
        border-left: 0;
        border-bottom: 3px solid transparent;
        border-right: 1px solid #f1f3f5;
    }

    .universe-list-item.active {
        border-bottom-color: #0d6efd;
    }

}

/* The chosen universe */
.universe-meta-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.4rem 1.25rem;
    padding: 0.6rem 0.9rem;
    margin-bottom: 0.5rem;
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: 0.25rem;
}

.universe-meta-title {
    font-size: 1rem;
    font-weight: 700;
}

.universe-meta strong {
    margin-right: 0.2rem;
}

.universe-meta.used strong {
    color: #0d6efd;
}

.universe-meta.free strong {
    color: #198754;
}

.universe-meta.clash strong {
    color: #dc3545;
}

.universe-selected {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.25rem;
    align-items: baseline;
    min-height: 2rem;
    padding: 0.35rem 0.9rem;
    margin-bottom: 0.5rem;
    background: #f8f9fa;
    border: 1px solid #dee2e6;
    border-radius: 0.25rem;
}

.universe-selected-name {
    font-weight: 700;
}

.universe-grid-wrap {
    padding: 2px;
    background: #e9ecef;
    border: 1px solid #dee2e6;
    border-radius: 0.25rem;
}

.universe-grid {
    display: grid;
    grid-template-columns: 2.6rem repeat(var(--universe-columns, 32), minmax(0, 1fr));
    grid-auto-rows: 3.6rem;
    gap: 2px;
}

.universe-row-label {
    padding-top: 2px;
    font-size: 0.7rem;
    font-weight: 600;
    text-align: right;
    color: #6c757d;
}

.universe-channel {
    padding: 2px 3px;
    font-size: 0.65rem;
    line-height: 1.1;
    color: #aab0b6;
    background: #fff;
    border: 1px solid #e3e6ea;
    border-radius: 2px;
    overflow: hidden;
    user-select: none;
}

.universe-fixture {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    padding: 2px 4px;
    overflow: hidden;
    line-height: 1.15;
    color: var(--universe-text, #fff);
    background: var(--universe-colour, #6c757d);
    border-radius: 2px;
    box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.15);
    cursor: pointer;
}

.universe-fixture-id {
    font-size: 0.85rem;
    font-weight: 700;
}

.universe-fixture-name {
    font-size: 0.75rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.universe-fixture-meta {
    margin-top: auto;
    font-size: 0.7rem;
    opacity: 0.85;
}

/* A fixture carrying on from the row above, or the universe before */
.universe-fixture.is-continued .universe-fixture-id::before {
    content: "\2192\00a0";
    opacity: 0.6;
}

.universe-fixture.is-overflow {
    border-right: 3px dashed rgba(0, 0, 0, 0.5);
}

.universe-fixture.is-selected {
    z-index: 3;
    outline: 3px solid #0d6efd;
    outline-offset: -1px;
}

.universe-fixture.is-clash {
    box-shadow: inset 0 0 0 2px #dc3545;
}

/* Fixtures sharing channels sit in lanes, one above the other, within the grid row */
.universe-fixture.is-laned {
    flex-direction: row;
    align-items: center;
    gap: 0.35rem;
    align-self: start;
    height: calc(100% / var(--universe-lanes, 1));
    transform: translateY(calc(var(--universe-lane, 0) * 100%));
    padding-top: 0;
    padding-bottom: 0;
}

.universe-fixture.is-laned .universe-fixture-meta {
    display: none;
}

.universe-fixture.is-laned .universe-fixture-id,
.universe-fixture.is-laned .universe-fixture-name {
    font-size: 0.7rem;
}

/* The channels more than one fixture is on */
.universe-clash-zone {
    z-index: 2;
    pointer-events: none;
    border-radius: 2px;
    background: repeating-linear-gradient(45deg, rgba(220, 53, 69, 0.55) 0, rgba(220, 53, 69, 0.55) 4px, transparent 4px, transparent 9px);
    box-shadow: inset 0 0 0 2px #dc3545;
    animation: universe-clash-pulse 1.8s ease-in-out infinite;
}

@keyframes universe-clash-pulse {
    0%, 100% { opacity: 0.65; }
    50% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {

    .universe-clash-zone {
        animation: none;
    }

}

.universe-legend {
    margin-top: 0.6rem;
}

.universe-legend-item {
    display: inline-flex;
    align-items: center;
    margin: 0.15rem;
    padding: 0.2rem 0.5rem;
    font-size: 0.9rem;
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: 0.25rem;
}

.universe-legend-count {
    margin-left: 0.4rem;
    font-size: 0.8rem;
    color: #868e96;
}

.universe-clash-card .card-header {
    color: #842029;
    background: #f8d7da;
}

.universe-clash-row {
    cursor: pointer;
}

.universe-clash-fixture {
    display: inline-block;
    margin-right: 1rem;
}

/* A universe with clashes - red instead of blue, active or not */
.universe-list-item.has-clash {
    color: #b02a37;
}

.universe-list-item.has-clash .universe-list-meta {
    color: #b02a37;
}

.universe-list-item.has-clash .universe-list-bar-fill {
    background: #dc3545;
}

.universe-list-item.has-clash.active {
    background: #f8d7da;
    color: #842029;
    border-left-color: #dc3545;
}

.universe-list-item.has-clash.active .universe-list-meta {
    color: #842029;
}

@media (max-width: 991.98px) {

    .universe-list-item.has-clash.active {
        border-bottom-color: #dc3545;
    }

}
