:root{
    --modal-content-background-color: #fff;
    --placement-font-color: #757575;
    --calendar-icon: url('/caddy/images/icons/calendar/Light Date icon.png');
}

body.dark {
    --modal-content-background-color: #141314;
    --calendar-icon: url('/caddy/images/icons/calendar/Dark Date icon.png');
}

/* Background scroll lock while a modal is open. JS sets body.top to the frozen scroll offset
   so the page stays visually put, then restores the scroll position on close. */
body.modal-scroll-lock {
    position: fixed;
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
}

/* Modal background overlay */
.modal {
    display: none;
    position: fixed;
    z-index: 1000;
    inset: 0;
    background-color: rgba(0,0,0,0.5);
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 16px;
    overflow: hidden;
    box-sizing: border-box;
}

.modal-content {
    background-color: var(--modal-content-background-color);
    color: var(--font-color);
    padding: 20px;
    border: 2px solid var(--background-color);
    border-radius: 12px;
    width: 400px;
    max-width: min(80%, 960px);
    max-height: calc(100vh - 32px);
    /* dvh matches the visible viewport on iPad, where 100vh is the toolbar-retracted
       height and holds the modal taller than the screen. Older engines keep the vh line. */
    max-height: calc(100dvh - 32px);
    box-shadow: 0 4px 12px rgba(0,0,0,0.3);
    position: relative;
    overflow-y: auto;
    box-sizing: border-box;
}

/* Floating, non-dimming checkout window (estimate page). The overlay is click-through
   so the estimate behind it stays interactive; only the window itself captures input.
   JS sets an explicit left/top/width/height and persists them. */
.modal.modal-floating {
    background-color: transparent;
    pointer-events: none;
    display: block;
    padding: 0;
}

.modal.modal-floating .modal-content {
    pointer-events: auto;
    position: fixed;
    margin: 0;
    max-width: none;
    max-height: none;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    box-shadow: 0 10px 32px rgba(0,0,0,0.4);
}

/* Header stays put as the drag grip; the form scrolls within the fixed window height. */
.checkout-floating > h2,
.checkout-floating > .checkout-header {
    flex: 0 0 auto;
}

.checkout-floating .modal-form {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
}

.checkout-floating .checkout-drag-handle {
    cursor: move;
    user-select: none;
    touch-action: none;
}

/* Bottom-right resize grip, pinned to the visible window corner. */
.checkout-floating .checkout-resize-handle {
    position: absolute;
    right: 2px;
    bottom: 2px;
    width: 16px;
    height: 16px;
    cursor: nwse-resize;
    touch-action: none;
    opacity: 0.55;
    z-index: 3;
    background: linear-gradient(
        135deg,
        transparent 0 45%,
        var(--font-color) 45% 55%,
        transparent 55% 70%,
        var(--font-color) 70% 80%,
        transparent 80%
    );
}

.checkout-floating .checkout-resize-handle:hover {
    opacity: 1;
}

.modal-content h2{
    margin-top: 0;
    color: var(--secondary-color);
    font-weight: 800;
    font-size: 1.5rem;
}

/* Header text */
.modal-content h2 {
    margin-top: 0;
    color: var(--secondary-color);
    font-weight: 700;
    font-size: 1.5rem;
    /* margin-bottom: 5px; */
}

.modal-content label {
    display: block;
    margin-top: 10px;
    font-weight: 600;
}

/* Checkboxes and radios are excluded: this rule is written for a text box, and forcing an opaque
   background over a native control is what left them painted blank white on iPad Safari, which
   draws the box and its tick through that background rather than on top of it. */
.modal-content input:not([type="checkbox"]):not([type="radio"]),
.modal-content input:not([type="checkbox"]):not([type="radio"]):focus,
.modal-content input:not([type="checkbox"]):not([type="radio"]):active {
    min-width: 96.5%;
    padding: 8px;
    margin-top: 5px;
    font-size: .9rem;
    font-weight: 500;
    border: 2px solid var(--background-color);
    border-radius: 6px;
    color: var(--font-color);
    background-color: var(--background-color) !important;
    outline: none;
    box-shadow: none;
}

.modal-content select {
    width: 100%;
    padding: 8px;
    margin-top: 5px;
    font-size: .9rem;
    font-weight: 500;
    border: 2px solid var(--background-color);
    border-radius: 6px;
    background-color: var(--background-color);
    margin-right: 5px;
    color: var(--font-color);
}

/* Text boxes only, as above: the min-width reset would collapse a focused checkbox */
.modal-content input:not([type="checkbox"]):not([type="radio"]):focus {
    border-color: var(--sub-background-color);
    outline: none;
    min-width: 0 !important;
}

/* Compile Modal */
.download-group {
    margin-bottom: 1rem;
}

.download-group h3 {
    margin: 0 0 0.4rem 0;
    font-size: 1rem;
}

.download-options {
    display: grid;
    grid-template-columns: 150px 150px; /* Two equal-width columns */
    gap: 10px 20px; /* row gap, column gap */
}

.download-options label {
    display: flex;
    align-items: center;
    gap: 6px; /* Space between checkbox and text */
}

/* Wrapper for input + icon */
.date-input-wrapper {
  position: relative;
  width: 100%;
}

/* Date Input Styling */
.modal-content input#projectDate {
  width: 95%;
  border: 1px solid var(--accent-color);
  border-radius: 6px;
  background-color: var(--modal-content-background-color);
  color: var(--font-color);
  font-size: .9rem;
  font-weight: 500;
  cursor: pointer;
}

.modal-content input#projectDate:focus {
  border-color: var(--accent-color-strong);
  outline: none;
}

/* Real clickable calendar icon */
.calendar-icon {
  position: absolute;
  right: 10px;
  top: 55%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  background-image: var(--calendar-icon);
  background-size: cover;
  background-repeat: no-repeat;
  cursor: pointer;
}

/* Flatpickr popup styling */
.flatpickr-calendar {
  background: var(--background-color) !important;
  border: 1px solid var(--accent-color) !important;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
}
/* Days */
.flatpickr-day {
  color: var(--font-color) !important;
}
.flatpickr-day:hover {
  background: var(--secondary-color) !important;  
  color: var(--background-color) !important;  
}
.flatpickr-day.selected,
.flatpickr-day.startRange,
.flatpickr-day.endRange,
.flatpickr-day.inRange {
  background: var(--primary-accent-color) !important;
  color: var(--background-color) !important;  
  font-weight: bold !important;
}
/* Weekday labels (Sun-Sat) */
span.flatpickr-weekday {
  background: var(--background-color) !important;
  color: var(--font-color) !important;
  font-weight: 600 !important;
  padding: 4px 0 !important;
  border: none !important;
  text-transform: uppercase !important;
  letter-spacing: 0.5px !important;
}
/* Month bar */
.flatpickr-months .flatpickr-month {
  background: var(--secondary-accent-color) !important;
  color: var(--font-color) !important;
  border-radius: 2px 2px 0 0 !important;
  padding: 2px 0 !important;
}
/* Month dropdown */
.flatpickr-monthDropdown-months {
  background: var(--secondary-accent-color) !important;
  color: var(--font-color) !important;
  padding: 2px 6px !important;
  font-weight: bold !important;
  cursor: pointer !important;
}
.flatpickr-monthDropdown-months option {
  background: var(--background-color) !important;
  color: var(--font-color) !important;
  text-align: center !important;
}
/* Year input */
.flatpickr-current-month .numInputWrapper input {
  background: transparent !important;
  color: var(--font-color) !important;
  font-weight: bold !important;
  border: none !important;
  outline: none !important;
  text-align: center !important;
  padding-right: 10px !important;
}
.flatpickr-current-month .numInputWrapper span {
  margin-left: 10px !important; 
}
/* Year up/down arrows */
.flatpickr-current-month .numInputWrapper span.arrowUp:after,
.flatpickr-current-month .numInputWrapper span.arrowDown:after {
  border-bottom-color: var(--font-color) !important;
  border-top-color: var(--font-color) !important;
}
/* Arrows */
.flatpickr-prev-month,
.flatpickr-next-month {
  color: var(--font-color) !important;
  fill: var(--font-color) !important;
}

/* Time picker (enableTime): keep text in the font color and stop the white hover/select background */
.flatpickr-time {
  background: var(--background-color) !important;
  border-top: 1px solid var(--accent-color) !important;
}
.flatpickr-time input,
.flatpickr-time .flatpickr-am-pm,
.flatpickr-time .flatpickr-time-separator {
  color: var(--font-color) !important;
  background: transparent !important;
}
.flatpickr-time input:hover,
.flatpickr-time input:focus,
.flatpickr-time .flatpickr-am-pm:hover,
.flatpickr-time .flatpickr-am-pm:focus {
  background: var(--sub-background-color) !important;
  color: var(--font-color) !important;
}
/* Time up/down arrows */
.flatpickr-time .numInputWrapper span.arrowUp:after {
  border-bottom-color: var(--font-color) !important;
}
.flatpickr-time .numInputWrapper span.arrowDown:after {
  border-top-color: var(--font-color) !important;
}

.required-star {
  color: red;
  margin-left: 4px;
  font-weight: bold;
}

#dropdownSelected{    
    position: relative;
    width: 95%;
    padding: 8px;
    margin-top: 5px;
    font-size: .9rem;
    font-weight: 400;
    border: 2px solid var(--background-color);
    border-radius: 6px;
    background-color: var(--modal-content-background-color);
    color: var(--placement-font-color);

    img{
        opacity: .7;
        position: absolute;
        right: 10px;
        top: 50%;
        transform: translateY(-50%);
        width: 10px;
        height: 10px;
    }
}

#dropdownSelected:hover {
    cursor: pointer;
    opacity: 1;
}

#dropdownList{
    display: none;
    position: relative;
    z-index: 1000;
    background-color: var(--modal-content-background-color);
    border: 2px solid var(--background-color);
    border-radius: 6px;
    width: 99%;
    max-height: 200px;
    overflow-y: auto;
}

.dropdown-option {
    padding: 8px;
    font-size: .9rem;
    font-weight: 500;
    color: var(--font-color);
    border: none;
}

.dropdown-option:hover {
    background-color: var(--secondary-accent-color);
    color: var(--font-color);
    cursor: pointer;
}

.modal-content button:not(.project-update-card-menu-btn):not(.custom-dropdown-trigger):not(.custom-dropdown-option):not(.de-copy-project-nav-btn):not(.admin-item-spec-sheet-delete-btn):not(.estimate-docs-delete-btn):not(.invite-add-files-pick):not(.invite-add-files-remove):not(.hour-rate-add-btn):not(.hour-rate-remove-btn):not(.sub-picker-chip-remove):not(.sub-picker-mode-btn):not(.sub-picker-pager-btn):not(.pl-filter-toggle):not(.pl-goto):not(.file-tree-folder-toggle):not(.file-tree-folder-delete):not(.estimate-docs-tab):not(.comm-split-btn):not(.comm-co-edit-toggle):not(.comm-co-edit-add):not(.comm-co-edit-del):not(.comm-paid-add):not(.comm-paid-del):not(.service-picker-row):not(.service-picker-group):not(.assurance-pair-remove):not(.admin-add-plus-btn) {
    margin-top: 15px;
    background-color: color-mix(in srgb, var(--secondary-accent-color) 18%, var(--background-color));
    color: var(--font-color);
    font: inherit;
    font-weight: 600;
    min-width: 100px;
    padding: 4px 8px;
    border: 1px solid var(--primary-accent-color);
    border-radius: 10px;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease;
}

.modal-content:not(.duplicate-project-modal):not(.modal-two-tone-question-wrap) button:not(.project-update-card-menu-btn):not(.custom-dropdown-trigger):not(.custom-dropdown-option):not(.pl-filter-toggle):not(.pl-goto):not(.comm-co-edit-toggle):not(.comm-co-edit-add):not(.comm-co-edit-del):not(.service-picker-row):not(.service-picker-group):not(.assurance-pair-remove):not(.admin-add-plus-btn):hover {
    border-color: var(--primary-color);
    background-color: var(--secondary-color);
}

.modal-content.modal-two-tone .modal-form .custom-dropdown-trigger {
    min-height: 40px;
    height: 40px;
    padding: 0 32px 0 12px;
    background: var(--background-color);
}

.button-row, .project-button-row {
    display: flex;
    gap: 12px;
    justify-content: flex-end;
}

.modal-content p {
  white-space: pre-line;
}

/* "Requested by <manager>" subtitle in the Changes Needed notes modal. */
.review-changes-modal-by {
  margin: -0.4rem 0 0.6rem 0 !important;
  font-size: 0.85rem;
  font-style: italic;
  opacity: 0.75;
  color: var(--font-color);
}

/* Deny-notes box in the "already denied" heads-up modal */
.madn-notes-box {
  margin-bottom: 0.75rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--other-color);
  border-radius: 6px;
  background: var(--sub-background-color);
}

.madn-notes-label {
  margin: 0 0 0.35rem 0;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.7;
  color: var(--font-color);
}

.madn-notes-text {
  margin: 0;
  white-space: pre-wrap;
  color: var(--font-color);
}

/* Close button (X) */
.close {
    color: var(--font-color);
    position: absolute;
    top: 14px;
    right: 16px;
    font-size: 24px;
    font-weight: bold;
    cursor: pointer;
    line-height: 1;
    margin: 0;
    float: none;
    z-index: 5;
}

.modal-content.modal-two-tone > .close {
    top: 16px;
    right: 18px;
}

.modal-content.modal-two-tone > h2 {
    padding-right: 56px;
}

/* The question layout moves .close inside .modal-two-tone-question, so the direct-child rule above
   stops matching and the X falls back to the bare .close with no reserved space. Give it the same
   offsets plus a hit area so it cannot sit on top of the content in the right panel. */
.modal-two-tone-question > .close {
    top: 10px;
    right: 12px;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
}

.modal-two-tone-question > .close:hover {
    background: color-mix(in srgb, var(--secondary-accent-color) 22%, transparent);
}

/* Close hover effect */
.close:hover {
    color: var(--secondary-color);
}

/* Action button inside modal */
.modal-action {
    margin-top: 15px;
    background-color: color-mix(in srgb, var(--secondary-accent-color) 18%, var(--background-color));
    color: var(--font-color);
    font: inherit;
    font-weight: 600;
    border: 1px solid var(--primary-accent-color);
    padding: 10px 20px;
    border-radius: 10px;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease;
}

.modal-action:hover {
    border-color: var(--primary-color);
    background-color: var(--secondary-color);
}

/* Scrollbar Styling */
.dropdown-list::-webkit-scrollbar {
  width: 6px;
}
.dropdown-list::-webkit-scrollbar-track {
  background: transparent;
}
.dropdown-list::-webkit-scrollbar-thumb {
  background-color: var(--accent-color);
  border-radius: 4px;
}
.dropdown-list::-webkit-scrollbar-thumb:hover {
  background-color: var(--background-color);
}
.dropdown-list::-webkit-scrollbar-button {
  display: none;
  height: 0;
}
.dropdown-list {
  scrollbar-color: var(--background-color);
}

/* shared project log */
.chat-modal {
    width: 600px;
    max-height: 80vh;
    overflow: hidden;
}

.chat-log-container {
    max-height: 60vh;
    overflow-y: auto;
    padding-right: 10px;
}

.chat-entry {
    padding: 12px;
    border-bottom: 1px solid #444;
}

.chat-header {
    display: flex;
    justify-content: space-between;
    font-size: 13px;
    margin-bottom: 6px;
    opacity: 0.8;
}

.chat-body {
    font-size: 15px;
}

/* unread dot on logs */
.chat-entry.unread {
    background-color: rgba(210, 63, 63, 0.08);
}

.chat-entry .chat-meta {
    font-size: 0.8rem;
    opacity: 0.8;
    display: flex;
    align-items: center;
    gap: 6px;
}

.chat-unread-dot {
    width: 8px;
    height: 8px;
    border-radius: 999px;
    background-color: var(--primary-accent-color, #d23f3f);
    flex-shrink: 0;
}

.chat-entry .chat-message {
    margin-top: 2px;
}

.modal-form textarea {
    width: 100%;
    min-height: 110px;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    font: inherit;
    line-height: 1.4;
    color: var(--font-color);
    background: var(--background-color);
    resize: vertical;
    box-sizing: border-box;
}

.modal-form textarea:focus-visible {
    outline: none;
}

.modal-form input,
.modal-form textarea {
    margin-top: 0.35rem;
}

.estimate-material-choice-option {
    display: block;
    margin-bottom: 0.75rem;
    cursor: pointer;
}

.estimate-material-choice-option input[type="radio"],
.estimate-material-choice-option input[type="checkbox"] {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.estimate-material-choice-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.85rem;
    flex-wrap: wrap;
}

.estimate-material-choice-help {
    font-size: 0.9rem;
    color: var(--font-color);
    opacity: 0.75;
}

.estimate-material-choice-toolbar-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    flex-wrap: wrap;
}

.estimate-material-choice-link-btn {
    border: none !important;
    background: transparent;
    font: inherit;
    padding: 0.2rem 0.2rem !important;
}

.estimate-material-choice-card {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.85rem 1rem;
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    background: var(--background-color);
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.estimate-material-choice-option:hover .estimate-material-choice-card {
    border-color: var(--primary-accent-color);
    background: color-mix(in srgb, var(--secondary-accent-color) 8%, var(--background-color));
}

.estimate-material-choice-option input[type="radio"]:checked + .estimate-material-choice-card,
.estimate-material-choice-option input[type="checkbox"]:checked + .estimate-material-choice-card {
    border-color: var(--primary-accent-color);
    background: color-mix(in srgb, var(--secondary-accent-color) 14%, var(--background-color));
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--secondary-accent-color) 18%, transparent);
}

.estimate-material-choice-dot {
    width: 18px;
    height: 18px;
    margin-top: 0.1rem;
    border: 2px solid var(--accent-color);
    border-radius: 50%;
    background: var(--background-color);
    position: relative;
    flex: 0 0 18px;
    box-sizing: border-box;
}

.estimate-material-choice-option input[type="checkbox"] + .estimate-material-choice-card .estimate-material-choice-dot {
    border-radius: 5px;
}

.estimate-material-choice-option input[type="radio"]:checked + .estimate-material-choice-card .estimate-material-choice-dot,
.estimate-material-choice-option input[type="checkbox"]:checked + .estimate-material-choice-card .estimate-material-choice-dot {
    border-color: var(--primary-accent-color);
}

.estimate-material-choice-option input[type="radio"]:checked + .estimate-material-choice-card .estimate-material-choice-dot::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--primary-accent-color);
    transform: translate(-50%, -50%);
}

.estimate-material-choice-option input[type="checkbox"]:checked + .estimate-material-choice-card .estimate-material-choice-dot::after {
    content: "";
    position: absolute;
    left: 5px;
    top: 1px;
    width: 4px;
    height: 9px;
    border: solid var(--primary-accent-color);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.estimate-material-choice-content {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 0;
}

.estimate-material-choice-content strong {
    font-size: 0.98rem;
    color: var(--font-color);
}

.estimate-material-choice-meta {
    font-size: 0.9rem;
    color: var(--font-color);
    opacity: 0.75;
    line-height: 1.35;
}

.estimate-material-choice-option-neither {
    margin-top: 1rem;
}

/* Two-tone modal layout */
.modal-content.modal-two-tone {
    padding: 0;
    overflow-y: auto;
    overflow-x: hidden;
    width: min(860px, 92vw);
    max-width: 92vw;
    max-height: calc(100vh - 32px);
    /* dvh matches the visible viewport on iPad, where 100vh is the toolbar-retracted
       height and holds the modal taller than the screen. Older engines keep the vh line. */
    max-height: calc(100dvh - 32px);
}

.modal-content.modal-two-tone h2 {
    margin: 0;
    padding: 18px 22px;
    background: color-mix(in srgb, var(--sub-background-color) 78%, var(--background-color) 22%);
    /* border-bottom: 1px solid var(--accent-color); */
}

/* Context subtitle that sits on its own line below the modal title, inside the header band. */
.modal-subtitle {
    display: block;
    margin-top: 6px;
    font-size: 0.9rem;
    font-weight: 500;
    color: color-mix(in srgb, var(--font-color) 65%, transparent);
}

/* Hint text ("Notes are required.") shown on its own line below a form label. */
.review-notes-hint {
    display: block;
    margin-top: 2px;
    font-size: 0.8rem;
    font-weight: 500;
    color: color-mix(in srgb, var(--font-color) 60%, transparent);
}

.modal-content.modal-two-tone p {
    margin: 0;
}

.modal-content.modal-two-tone .modal-form {
    display: grid;
    grid-template-columns: 220px minmax(0, 1fr);
    gap: 10px;
    padding-top: 5px;
    padding-right: 10px;
    align-items: start;
    background:
        linear-gradient(
            to right,
            color-mix(in srgb, var(--sub-background-color) 78%, var(--background-color) 22%) 0,
            color-mix(in srgb, var(--sub-background-color) 78%, var(--background-color) 22%) 220px,
            color-mix(in srgb, var(--background-color) 88%, black 12%) 220px,
            color-mix(in srgb, var(--background-color) 88%, black 12%) 100%
        );
}

.modal-content.modal-two-tone .modal-form > label {
    display: flex;
    grid-column: 1;
    align-items: center;
    margin: 0;
    padding: 14px 18px;
    background: transparent;
    /* border-top: 1px solid var(--accent-color); */
    /* border-right: 1px solid var(--accent-color); */
    min-height: 52px;
    box-sizing: border-box;
}

.modal-content.modal-two-tone .modal-form > input,
.modal-content.modal-two-tone .modal-form > select,
.modal-content.modal-two-tone .modal-form > textarea,
.modal-content.modal-two-tone .modal-form > .date-input-wrapper,
.modal-content.modal-two-tone .modal-form > #dropdownSelected,
.modal-content.modal-two-tone .modal-form > #dropdownList,
.modal-content.modal-two-tone .modal-form > div:not(.button-row):not(.project-button-row):not(.cp-error):not(.formula-hour-button-row):not(.move-admin-confirm-warning):not(.move-admin-confirm-row):not(.checkout-side):not(.cp-dev-row):not(.service-modal-note):not(.project-update-mention-menu) {
    grid-column: 2;
    background: transparent;
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
}

/* Ensure hidden rows are fully removed in two-tone grid forms */
.modal-content.modal-two-tone .modal-form > .hidden,
.modal-content.modal-two-tone .modal-form > .custom-dropdown.hidden {
    display: none !important;
}

/* A hidden two-tone form itself: the display:grid above outranks the plain .hidden rule, so a
   multi-step modal needs this to actually hide the step it is not on. */
.modal-content.modal-two-tone .modal-form.hidden {
    display: none !important;
}

/* Add Item modal Approve-into field: set apart from the fields above it as the last group */
.modal-content.modal-two-tone .modal-form > .create-admin-item-scope-label,
.modal-content.modal-two-tone .modal-form > .custom-dropdown:has(#create-admin-item-scope) {
    margin-top: 12px;
}

/* Reorder Equipment modal: drag to reorder equipment systems */
.estimate-system-reorder-modal {
    width: min(560px, 92vw);
}

.estimate-system-reorder-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-height: min(46vh, 420px);
    overflow: auto;
    margin-top: 12px;
    /* Extra room above and below so a row can be dragged past the ends and still dropped */
    padding: 40px 2px;
}

.estimate-system-reorder-row {
    display: grid;
    grid-template-columns: 18px 28px minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 10px;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--sub-background-color);
    color: var(--font-color);
    box-sizing: border-box;
    cursor: grab;
}

.estimate-system-reorder-row.is-current {
    border-color: var(--primary-accent-color);
    background: color-mix(in srgb, var(--primary-accent-color) 12%, var(--sub-background-color) 88%);
}

.estimate-system-reorder-row.is-dragging {
    opacity: 0.5;
    cursor: grabbing;
}

.estimate-system-reorder-row.is-drop-target {
    box-shadow: inset 0 2px 0 0 var(--primary-accent-color);
}

.estimate-system-reorder-row.is-drop-target-after {
    box-shadow: inset 0 -2px 0 0 var(--primary-accent-color);
}

.estimate-system-reorder-handle {
    width: 18px;
    height: 14px;
    background-image: linear-gradient(
        to bottom,
        var(--font-color) 0,
        var(--font-color) 2px,
        transparent 2px,
        transparent 6px,
        var(--font-color) 6px,
        var(--font-color) 8px,
        transparent 8px,
        transparent 12px,
        var(--font-color) 12px,
        var(--font-color) 14px
    );
    opacity: 0.55;
}

.estimate-system-reorder-position {
    font-size: 0.85rem;
    font-weight: 600;
    text-align: right;
    opacity: 0.75;
}

.estimate-system-reorder-name {
    min-width: 0;
    text-align: left;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.estimate-system-reorder-badge {
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 600;
    background: var(--primary-accent-color);
    color: var(--modal-content-background-color);
    white-space: nowrap;
}

/* Add Contact modal: roles multi-select (checkbox list) */
.modal-content .create-admin-sub-roles,
.modal-content .estimate-materials-export-options {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 8px 0;
    padding: 6px;
    max-height: 380px;
    overflow-y: auto;
    border: 1px solid color-mix(in srgb, var(--font-color) 18%, transparent);
    border-radius: 8px;
}

.modal-content .create-admin-sub-role-option,
.modal-content .estimate-materials-export-option {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    margin: 0;
    padding: 9px 11px;
    border-radius: 6px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.12s ease;
}

.modal-content .create-admin-sub-role-option:hover,
.modal-content .estimate-materials-export-option:hover {
    background-color: color-mix(in srgb, var(--font-color) 8%, transparent);
}

.modal-content .create-admin-sub-role-option:has(input[type="checkbox"]:checked),
.modal-content .estimate-materials-export-option:has(input[type="checkbox"]:checked) {
    background-color: var(--accent-color);
}

/* Reset the global .modal-content input box styling for these checkboxes so they
   render as a normal checkbox sitting inline to the left of the label text. */
.modal-content .create-admin-sub-role-option input[type="checkbox"],
.modal-content .estimate-materials-export-option input[type="checkbox"] {
    flex: 0 0 auto;
    width: 16px;
    min-width: 16px;
    height: 16px;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    background-color: transparent !important;
    accent-color: var(--accent-color-strong, var(--accent-color));
    cursor: pointer;
}

.modal-content .create-admin-sub-role-option input[type="checkbox"]:disabled {
    cursor: not-allowed;
}

.modal-content .create-admin-sub-role-option span,
.modal-content .estimate-materials-export-option span {
    flex: 1 1 auto;
    text-align: left;
}

/* Create-project dev/test flag row: full-width, right column only (matches .cp-error). */
.modal-content.modal-two-tone .modal-form > .cp-dev-row {
    grid-column: 2;
}

.modal-content .cp-dev-option {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    margin: 0;
    cursor: pointer;
}

/* Reset the global .modal-content input box styling so the checkbox renders inline
   to the left of its label text. */
.modal-content .cp-dev-option input[type="checkbox"] {
    flex: 0 0 auto;
    width: 16px;
    min-width: 16px;
    height: 16px;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    background-color: transparent !important;
    accent-color: var(--accent-color-strong, var(--accent-color));
    cursor: pointer;
}

.modal-content .cp-dev-option span {
    flex: 1 1 auto;
    text-align: left;
}

/* New Service Job, tech only: the gap keeps the acknowledgement apart from the Office row below */
.modal-content #csq-no-ticket-row {
    margin-bottom: 14px;
    margin-top: -20px;
}

/* OR between the ticket box and the acknowledgement, with a rule on either side */
.modal-content .csq-or-divider {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 8px 0;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.05em;
    color: color-mix(in srgb, var(--font-color) 60%, transparent);
}

.modal-content .csq-or-divider::before,
.modal-content .csq-or-divider::after {
    content: "";
    flex: 1 1 auto;
    border-top: 1px solid color-mix(in srgb, var(--font-color) 20%, transparent);
}

/* New Service Job, tech only: no ticket acknowledgement under the ticket box, checkbox left and text right */
.modal-content .csq-no-ticket-option {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-weight: 500;
    cursor: pointer;
}

.modal-content .csq-no-ticket-option input[type="checkbox"] {
    flex: 0 0 auto;
    width: 16px;
    min-width: 16px !important;
    height: 16px;
    margin: 0;
    padding: 0 !important;
    border: none !important;
    border-radius: 0;
    background-color: transparent !important;
    accent-color: var(--accent-color-strong, var(--accent-color));
    cursor: pointer;
}

.modal-content .csq-no-ticket-option span {
    flex: 1 1 auto;
    text-align: left;
}

/* Multi-role assignment modal: a checklist of roles, checkbox left + label right. */
.modal-content .admin-users-roles-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.modal-content .admin-users-role-option {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    margin: 0;
    min-width: 200px;
    padding: 4px 8px;
    margin-bottom: 5px;
    border-radius: 6px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.12s ease;
}

.modal-content .admin-users-role-option:hover {
    background-color: color-mix(in srgb, var(--font-color) 8%, transparent);
}

.modal-content .admin-users-role-option:has(input[type="checkbox"]:checked) {
    background-color: var(--accent-color);
}

/* Reset the global ".modal-content input" min-width:96.5% so these render as
   normal small checkboxes inline to the left of the label text. */
.modal-content .admin-users-role-option input[type="checkbox"] {
    flex: 0 0 auto;
    width: 16px;
    min-width: 16px;
    height: 16px;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    background-color: transparent !important;
    accent-color: var(--accent-color-strong, var(--accent-color));
    cursor: pointer;
}

.modal-content .admin-users-role-option span {
    flex: 1 1 auto;
    text-align: left;
}

/* Role picker ("View as Role") */
.role-picker-subtitle {
    display: block;
    margin-top: 4px;
    font-size: 0.8rem;
    font-weight: 400;
    color: var(--font-color);
    opacity: 0.75;
}

.modal-content .role-picker-empty {
    padding: 8px 4px;
    opacity: 0.75;
}

/* The active toggle sits in the right (control) column of the two-tone grid. */
.modal-content.modal-two-tone .modal-form > label.role-picker-active-row {
    grid-column: 2;
    min-height: 0;
    padding: 10px 18px;
    font-weight: 500;
}

/* Keep the warning + confirm checkbox in the right (content) column only,
   matching how .cp-error and .button-row sit in the two-tone grid. */
.modal-content.modal-two-tone .modal-form > .move-admin-confirm-warning,
.modal-content.modal-two-tone .modal-form > .move-admin-confirm-row {
    grid-column: 2;
}

.modal-content .move-admin-confirm-warning {
    /* margin: 8px 16px 0; */
    padding: 10px 12px;
    border-radius: 8px;
    background: color-mix(in srgb, #d9534f 16%, transparent);
    font-size: 0.85rem;
}

.modal-content .move-admin-confirm-row {
    padding: 4px 4px;
}

/* Sales action follow-up modal: stack the note flag, question, textbox and hint vertically */
.modal-content .saf-required {
    font-size: 0.85rem;
    font-weight: 600;
    color: #d9534f;
}

.modal-content .saf-hint {
    margin-top: 8px;
    font-size: 0.82rem;
    font-style: italic;
    opacity: 0.8;
}

/* Linked project name highlighted so it stands out from the rest of the question */
.modal-content .saf-project {
    font-weight: 700;
    color: var(--primary-color);
}

.modal-content .saf-hint .saf-action-name {
    font-weight: 700;
    font-style: normal;
    color: var(--font-color);
}

/* Checkbox sits to the LEFT, label text to the RIGHT, both inline on one line.
   Resets the global ".modal-content input" min-width:96.5% / forced background
   so the box renders as a normal small checkbox. */
.modal-content .move-admin-confirm-option {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-weight: 500;
    font-size: 0.85rem;
    cursor: pointer;
}

.modal-content .move-admin-confirm-option input[type="checkbox"] {
    flex: 0 0 auto;
    width: 16px;
    min-width: 16px;
    height: 16px;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    background-color: transparent !important;
    accent-color: var(--accent-color-strong, var(--accent-color));
    cursor: pointer;
}

.modal-content .move-admin-confirm-option span {
    flex: 1 1 auto;
    text-align: left;
}

/* Live summary of the currently-selected roles, shown under the roles list */
.modal-content .create-admin-sub-selected-roles {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    padding: 6px 0;
    min-height: 28px;
}

.modal-content .create-admin-sub-selected-chip {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--font-color);
    background-color: color-mix(in srgb, var(--accent-color) 35%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent-color) 55%, transparent);
}

.modal-content .create-admin-sub-selected-empty {
    font-size: 0.85rem;
    font-style: italic;
    opacity: 0.7;
}

/* Two-tone question modal layout */
.modal-content.modal-two-tone.modal-two-tone-question-wrap {
    padding: 0;
    overflow-y: auto;
    overflow-x: hidden;
    width: min(860px, 92vw);
    max-width: 92vw;
    max-height: calc(100vh - 64px);
    /* dvh for the same reason as the modal shells above */
    max-height: calc(100dvh - 64px);
}

/* The tinted column is a gradient on this grid, so it must be clipped to the modal's own
   12px radius or it paints square past the rounded corners. */
.modal-two-tone-question {
    display: grid;
    /* minmax pins the tinted track to exactly 220px: a bare 220px is still a minimum, so a
       long unbroken title grows it past the gradient's stop and the panel overhangs the tint */
    grid-template-columns: minmax(0, 220px) minmax(0, 1fr);
    position: relative;
    border-radius: 12px;
    overflow: hidden;
    background:
        linear-gradient(
            to right,
            color-mix(in srgb, var(--sub-background-color) 78%, var(--background-color) 22%) 0,
            color-mix(in srgb, var(--sub-background-color) 78%, var(--background-color) 22%) 220px,
            color-mix(in srgb, var(--background-color) 88%, black 12%) 220px,
            color-mix(in srgb, var(--background-color) 88%, black 12%) 100%
        );
}

/* border-box or the 1px border adds to the 220px grid track. min-width: 0 stops a long title
   from forcing the track past 220px on its min-content size, which pushes the panel out
   beyond the gradient's colour stop so the tint and the divider stop in different places. */
.modal-two-tone-question-left {
    box-sizing: border-box;
    min-width: 0;
    padding: 18px 22px;
    border-right: 1px solid var(--accent-color);
}

/* overflow-wrap because a long item name may have no space to break on and would otherwise
   set a min-content width wider than the panel */
.modal-two-tone-question-left h2 {
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
    padding: 0;
}

.modal-two-tone-question-right {
    padding: 18px 22px;
    min-width: 0;
}

.modal-two-tone-question-right p:first-child {
    margin-top: 0;
}

.modal-two-tone-question-right .button-row,
.modal-two-tone-question-right .project-button-row,
.modal-two-tone-question-right .formula-hour-button-row {
    margin-top: 1rem;
    justify-content: flex-end;
    gap: 10px;
}

/* A form inside a question modal's right panel stacks normally: the 220px label grid is meant for
   standalone two-tone forms, not the title-left/content-right question layout. Higher specificity
   than the grid rule so it wins wherever a .modal-form lands in the question's right column. */
.modal-content.modal-two-tone .modal-two-tone-question-right .modal-form {
    display: flex;
    flex-direction: column;
    gap: 8px;
    background: none;
    padding: 0;
}

.modal-content.modal-two-tone .modal-two-tone-question-right .modal-form > label {
    grid-column: auto;
    display: block;
    padding: 0;
    min-height: 0;
}

/* An input wrapped for a unit suffix is styled here too, so it IS an ordinary field rather than one
   restating these values somewhere else and drifting from them. */
.modal-content.modal-two-tone .modal-form > input,
.modal-content.modal-two-tone .modal-form > select,
.modal-content.modal-two-tone .modal-form > textarea,
.modal-content.modal-two-tone .modal-form > .comm-pct-field > input {
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    min-height: 40px;
    background: var(--background-color);
}

.modal-content.modal-two-tone .modal-form > textarea {
    min-height: 110px;
    resize: vertical;
    margin-top: 0.35rem;
}

.modal-prefix-input-wrap {
    display: flex;
    align-items: center;
    gap: 0.55rem;
}

.modal-prefix-input-label {
    font-weight: 700;
    color: var(--text-color);
    white-space: nowrap;
}

.modal-prefix-input-wrap > input {
    flex: 1 1 auto;
    min-width: 0;
}

/* Keep modal errors on the right side only */
.modal-content.modal-two-tone .modal-form > .cp-error {
    grid-column: 2;
    margin: 0;
    /* padding: 10px 16px 0 16px; */
    background: color-mix(in srgb, var(--background-color) 88%, black 12%);
    min-width: 0;
    box-sizing: border-box;
    text-align: left;
}

/* Estimator/Salesperson control: the dropdown plus optional "+ Add new" person inputs */
.cp-person-control {
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: 100%;
    min-width: 0;
}

/* The First/Last/Email inputs revealed by the "+ Add new" option */
.cp-person-new {
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: 100%;
    min-width: 0;
}

/* Keep the inputs hidden until "+ Add new" is chosen (beats .cp-person-new's display) */
.cp-person-new.hidden {
    display: none;
}

/* Reset the global .modal-content input min-width so these inputs fit their cell */
.cp-person-new input {
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
}

/* People group (estimators + salespeople) under the single "People" label; each section
   inside is a contacts-style .pc-role-section rendered by createProjectPeopleRowsManager. */
.cp-people-group {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: 100%;
    min-width: 0;
}

/* Note shown when the salespeople are frozen by an approved commission. */
.cp-lock-note {
    font-size: 12px;
    color: var(--secondary-color);
    background: var(--accent-color);
    border: 1px solid var(--other-color);
    border-radius: 8px;
    padding: 8px 10px;
}
/* Hidden on its own class rather than the global .hidden, which the commissions page does not define. */
.pc-role-section-note-off {
    display: none;
}

/* Note explaining why a sales split totals 70% instead of 100% (the job has an estimator). */
.pc-role-section-note {
    font-size: 12px;
    color: var(--font-color);
    background: var(--accent-color);
    border: 1px solid var(--other-color);
    border-radius: 8px;
    padding: 8px 10px;
    margin-bottom: 8px;
}

/* A read-only people section: dimmed and non-interactive, but still legible. */
.pc-role-section-disabled {
    opacity: 0.75;
}
.pc-role-section-disabled select,
.pc-role-section-disabled input {
    cursor: not-allowed;
}

/* Light-mode trash icon for card remove buttons (dark mode overridden in palette.css).
   Also fixes the contact cards, whose light-mode icon rule was missing. */
.pc-contact-remove-icon {
    content: url("/caddy/images/icons/trashcan/Light Trashcan.png");
    width: 18px;
    height: 18px;
    display: block;
    pointer-events: none;
}

/* Inline "?" help icon with a hover/focus bubble, used next to modal field labels */
.modal-content .modal-field-help {
    position: relative;
    display: inline-flex;
    align-items: center;
    margin-left: 6px;
    vertical-align: middle;
    cursor: help;
}
.modal-content .modal-field-help-icon {
    width: 16px;
    height: 16px;
    border: 1px solid var(--accent-color);
    border-radius: 999px;
    background: var(--background-color);
    color: var(--font-color);
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.modal-content .modal-field-help-bubble {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 30;
    width: 240px;
    max-width: 60vw;
    padding: 8px 10px;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--background-color);
    color: var(--font-color);
    font-size: 12px;
    font-weight: 400;
    line-height: 1.4;
    box-shadow: 0 8px 18px rgba(0, 0, 0, 0.18);
    opacity: 0;
    pointer-events: none;
    transform: translateY(-4px);
    transition: opacity 0.15s ease, transform 0.15s ease;
}
.modal-content .modal-field-help:hover .modal-field-help-bubble,
.modal-content .modal-field-help:focus-within .modal-field-help-bubble {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
}

/* Duplicate-account warning rendered inside the create-form error area */
.cp-error .cp-dup-msg {
    font-weight: 600;
}
.cp-error .cp-dup-list {
    margin: 4px 0 0;
    padding-left: 18px;
}
.cp-error .cp-dup-detail {
    opacity: 0.75;
}

.modal-content.modal-two-tone .button-row,
.modal-content.modal-two-tone .project-button-row {
    grid-column: 2;
    margin: 0;
    padding: 16px 1px 18px 18px;
    background: color-mix(in srgb, var(--background-color) 88%, black 12%);
    border-top: 1px solid var(--accent-color);
    justify-content: flex-end;
}

.modal-content.modal-two-tone .close.modal-close-hidden {
    display: none;
}

#admin-hour-existing-list {
  scrollbar-width: thin;
  scrollbar-color: var(--sub-background-color) var(--background-color);
}

#admin-hour-existing-list::-webkit-scrollbar {
  width: 12px;
}

#admin-hour-existing-list::-webkit-scrollbar-track {
  background: var(--background-color);
  border-radius: 6px;
}

#admin-hour-existing-list::-webkit-scrollbar-thumb {
  background: var(--sub-background-color);
  border-radius: 6px;
  border: 2px solid var(--background-color);
}

#admin-hour-existing-list::-webkit-scrollbar-thumb:hover {
  background: var(--accent-color);
}

.modal-content,
.modal-content.modal-two-tone,
.modal-content.modal-two-tone.modal-two-tone-question-wrap {
    scrollbar-width: thin;
    scrollbar-color: var(--sub-background-color) var(--background-color);
}

.modal-content::-webkit-scrollbar,
.modal-content.modal-two-tone::-webkit-scrollbar,
.modal-content.modal-two-tone.modal-two-tone-question-wrap::-webkit-scrollbar {
    width: 12px;
}

.modal-content::-webkit-scrollbar-track,
.modal-content.modal-two-tone::-webkit-scrollbar-track,
.modal-content.modal-two-tone.modal-two-tone-question-wrap::-webkit-scrollbar-track {
    background: var(--background-color);
    border-radius: 6px;
}

.modal-content::-webkit-scrollbar-thumb,
.modal-content.modal-two-tone::-webkit-scrollbar-thumb,
.modal-content.modal-two-tone.modal-two-tone-question-wrap::-webkit-scrollbar-thumb {
    background: var(--sub-background-color);
    border-radius: 6px;
    border: 2px solid var(--background-color);
}

.modal-content::-webkit-scrollbar-thumb:hover,
.modal-content.modal-two-tone::-webkit-scrollbar-thumb:hover,
.modal-content.modal-two-tone.modal-two-tone-question-wrap::-webkit-scrollbar-thumb:hover {
    background: var(--accent-color);
}

/* Hide number input steppers everywhere */
input[type="number"] {
    -moz-appearance: textfield;
    appearance: textfield;
}

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* Hide the raw <select> until JS enhances it into a custom dropdown, so the
   unstyled native control doesn't flash on page load. Once enhanced it gains
   .custom-dropdown-native and the styled trigger takes over. */
select[data-custom-dropdown]:not(.custom-dropdown-native) {
    opacity: 0;
}

.custom-dropdown-native {
    position: absolute;
    inset: 0;
    opacity: 0;
    pointer-events: none;
}

.custom-dropdown-trigger {
    min-width: 90px;
    min-height: 40px;
    padding: 8px 35px 8px 12px;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--sub-background-color);
    color: var(--font-color);
    font: inherit;
    font-size: 0.9rem;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
    position: relative;
    box-sizing: border-box;
}

.custom-dropdown {
    position: relative;
    min-width: 0;
}

.modal-content.modal-two-tone .modal-form > .custom-dropdown {
    width: 100%;
    min-width: 0;
    margin: 0;
    margin-top: 0.35rem;
    background: transparent;
    box-sizing: border-box;
}

/* Reusable arbitrary-depth category flyout field (createCategoryFlyoutPicker). The field is a
   plain host div with a trigger button, so it mirrors the custom-dropdown trigger layout. */
.category-flyout-field {
    position: relative;
    min-width: 0;
    width: 100%;
    box-sizing: border-box;
}

.modal-content.modal-two-tone .modal-form > .category-flyout-field {
    margin-top: 0.35rem;
}

.category-flyout-field .category-flyout-trigger {
    width: 100%;
}

.category-flyout-field .category-flyout-trigger.is-open {
    border-color: var(--primary-accent-color);
}

.category-flyout-field .category-flyout-trigger.is-placeholder .custom-dropdown-label {
    opacity: 0.7;
}

.custom-dropdown-trigger::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 12px;
    width: 10px;
    height: 10px;
    border-right: 2px solid var(--font-color);
    border-bottom: 2px solid var(--font-color);
    transform: translateY(-70%) rotate(45deg);
    pointer-events: none;
    opacity: 0.85;
}

.custom-dropdown.is-open .custom-dropdown-trigger {
    border-color: var(--primary-accent-color);
}

.custom-dropdown-label {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.custom-dropdown-menu {
    display: none;
    position: absolute;
    left: 0;
    width: max-content;
    min-width: 100%;
    max-width: min(500px, calc(100vw - 32px));
    max-height: 240px;
    overflow-y: auto;
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    background: var(--background-color);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.28);
    z-index: 2000;
    padding: 4px;
    box-sizing: border-box;
    white-space: nowrap;
}

.custom-dropdown.is-open .custom-dropdown-menu {
    display: flex;
    flex-direction: column;
}

.custom-dropdown-menu.is-portaled {
    position: fixed;
    z-index: 100000;
    display: flex;
    flex-direction: column;
}

/* Optional search box for dropdowns with data-dropdown-search */
.custom-dropdown-search {
    position: sticky;
    top: 0;
    z-index: 1;
    flex: 0 0 auto;
    width: 100%;
    box-sizing: border-box;
    margin-bottom: 4px;
    padding: 6px 8px;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--background-color);
    color: var(--font-color);
    font: inherit;
    font-size: 14px;
}

.custom-dropdown-search:focus {
    outline: none;
    border-color: var(--primary-color);
}

.custom-dropdown-option-hidden {
    display: none !important;
}

.custom-dropdown-empty {
    padding: 6px 8px;
    color: var(--other-color);
    font-size: 14px;
    text-align: center;
}

.custom-dropdown-empty.hidden {
    display: none !important;
}

/* "Show all N (type to search)" footer for capped large-list dropdowns */
.custom-dropdown-show-more {
    color: var(--other-color);
    font-style: italic;
    font-size: 13px;
    text-align: center;
    justify-content: center;
}

/* Non-selectable group header for optgroup-backed dropdowns (tab -> subcategory) */
.custom-dropdown-group-label {
    padding: 6px 8px 2px;
    margin-top: 2px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--other-color);
    pointer-events: none;
}

.custom-dropdown-group-label.custom-dropdown-option-hidden {
    display: none !important;
}

/* Pinned "Other" row that opens a side flyout (data-flyout-other-values dropdowns) */
.custom-dropdown-option-other {
    display: flex;
    align-items: center;
    gap: 8px;
}

.custom-dropdown-option-other.is-flyout-open {
    background: var(--sub-background-color);
}

.custom-dropdown-flyout-caret {
    flex: 0 0 auto;
    margin-left: auto;
    font-size: 16px;
    line-height: 1;
    color: var(--other-color);
}

/* The portaled flyout reuses .custom-dropdown-menu.is-portaled for its frame */
.custom-dropdown-flyout-list {
    display: flex;
    flex-direction: column;
}

.custom-dropdown-option:hover {
    background: var(--sub-background-color);
}

/* .custom-dropdown-option.is-selected {
    background: var(--sub-background-color);
    font-weight: 400;
} */

.custom-dropdown-option {
    width: 100%;
    padding: 6px 8px;
    background: transparent;
    border: none;
    border-radius: 8px;
    color: var(--font-color);
    font: inherit;
    text-align: left;
    cursor: pointer;
    font-size: 15px;
    box-sizing: border-box;
}

/* An option carrying a data-sub second line, e.g. a contact's email and phone under their name.
   Only these stack: every other option keeps the single line layout above. */
.custom-dropdown-option-stacked {
    display: flex;
    flex-direction: column;
    gap: 1px;
    line-height: 1.35;
}

.custom-dropdown-option-main {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Smaller and muted, so the name still leads the row */
.custom-dropdown-option-sub {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--other-color);
    font-size: 0.8rem;
}

/* Multi-select option rows show a checkbox indicator */
.custom-dropdown-option-multi {
    display: flex;
    align-items: center;
    gap: 8px;
}

.custom-dropdown-option-text {
    flex: 1 1 auto;
    min-width: 0;
}

.custom-dropdown-check {
    flex: 0 0 auto;
    width: 15px;
    height: 15px;
    border: 1.5px solid var(--other-color);
    border-radius: 4px;
    box-sizing: border-box;
    position: relative;
}

.custom-dropdown-option-multi.is-selected .custom-dropdown-check {
    background: var(--primary-color);
    border-color: var(--primary-color);
}

.custom-dropdown-option-multi.is-selected .custom-dropdown-check::after {
    content: "";
    position: absolute;
    left: 4px;
    top: 1px;
    width: 4px;
    height: 8px;
    border: solid var(--background-color);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.custom-dropdown-option:first-child {
    border-top-left-radius: 8px;
    border-top-right-radius: 8px;
}

.custom-dropdown-option:last-child {
    border-bottom-left-radius: 8px;
    border-bottom-right-radius: 8px;
}

/* Custom dropdown scrollbar */
.custom-dropdown-menu {
    scrollbar-width: thin;
    scrollbar-color: var(--accent-color) var(--background-color);
}

.custom-dropdown-menu::-webkit-scrollbar {
    width: 10px;
}

.custom-dropdown-menu::-webkit-scrollbar-track {
    background: var(--background-color);
    border-radius: 999px;
}

.custom-dropdown-menu::-webkit-scrollbar-thumb {
    background: var(--accent-color);
    border-radius: 999px;
    border: 2px solid var(--background-color);
}

.custom-dropdown-menu::-webkit-scrollbar-thumb:hover {
    background: var(--primary-accent-color);
}

.custom-dropdown-menu::-webkit-scrollbar-corner {
    background: transparent;
}

.admin-add-hours-now-message {
    padding: 14px 18px;
    line-height: 1.5;
    min-height: 52px;
    align-items: center;
}

.de-copy-modal-form {
    position: relative;
}

.de-copy-loading-overlay {
    position: absolute;
    inset: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.28);
    border-radius: 0 0 12px 12px;
}

.de-copy-loading-overlay.hidden {
    display: none;
}

.de-copy-loading-gif {
    width: 64px;
    height: 64px;
    object-fit: contain;
    pointer-events: none;
}

.create-admin-item-manufacturer-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.create-admin-item-price-row {
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    padding: 10px;
    background: var(--background-color);
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.create-admin-item-price-row-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.create-admin-item-price-default-wrap {
    display: inline-flex !important;
    align-items: center;
    gap: 8px;
    margin-top: 0 !important;
}

.create-admin-item-price-default-wrap input[type="radio"] {
    min-width: 16px !important;
    width: 16px;
    height: 16px;
    margin: 0;
}

.create-admin-item-price-list {
    border: 1px var(--background-color);
}

.create-admin-item-price-row .create-admin-item-price-value, .create-admin-item-price-list-value {
    width: 100%;
    min-width: 0 !important;
    border: 1px solid var(--accent-color) !important;
    border-radius: 8px;
    background: var(--background-color) !important;
    box-sizing: border-box;
}

.create-admin-item-price-row .create-admin-item-price-value:focus,
.create-admin-item-price-row .create-admin-item-price-value:focus-visible {
    box-shadow: none;
}









/* Fullscreen overlay */
.screensaver {
  position: fixed;
  inset: 0;
  background: var(--background-color);
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity 1s ease;
  z-index: 9999;
}

.screensaver.active {
  opacity: 1;
  pointer-events: auto;
}

.screensaver img {
  height: 100px;
  position: absolute;
  transform: translate(-50%, -50%) scale(1) !important;
  image-rendering: auto;
}

.custom-dropdown.is-disabled .custom-dropdown-trigger,
.custom-dropdown-trigger:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    pointer-events: none;
}

.estimate-logs-footer {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 10px;
  margin-top: 1rem;
}

.estimate-logs-modal {
    width: min(860px, calc(100vw - 40px)) !important;
}

.estimate-logs-wrap {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-height: min(62vh, 720px);
    overflow-y: auto;
    margin-top: 14px;
    padding-right: 8px;
}

.estimate-log-row {
    padding: 14px 16px;
    border: 1px solid var(--accent-color);
    border-left-width: 4px;
    border-radius: 12px;
    background: var(--sub-background-color);
}

.estimate-log-row-create {
    border-left-color: #3d8b5a;
}

.estimate-log-row-update {
    border-left-color: var(--primary-accent-color);
}

.estimate-log-row-delete {
    border-left-color: #b85454;
}

.estimate-log-row-export {
    border-left-color: #907331;
}

.estimate-log-row-import {
    border-left-color: #3a6f8f;
}

.estimate-log-row-submit {
    border-left-color: #2f6f4f;
}

.estimate-log-row-reopen {
    border-left-color: #b07d2b;
}

.estimate-log-row-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 8px;
}

.estimate-log-row-meta-left {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.estimate-log-time {
    font-size: 0.85rem;
    font-weight: 700;
    opacity: 0.75;
}

.estimate-log-user {
    font-size: 0.9rem;
    opacity: 0.92;
    word-break: break-word;
}

.estimate-log-badges {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 8px;
}

.estimate-log-badge {
    display: inline-flex;
    align-items: center;
    padding: 4px 8px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    background: color-mix(in srgb, var(--secondary-accent-color) 35%, transparent);
}

.estimate-log-badge-action {
    border: 1px solid transparent;
}

.estimate-log-badge-action-create {
    background: color-mix(in srgb, #3d8b5a 20%, transparent);
    border-color: color-mix(in srgb, #3d8b5a 48%, transparent);
}

.estimate-log-badge-action-update {
    background: color-mix(in srgb, var(--primary-accent-color) 20%, transparent);
    border-color: color-mix(in srgb, var(--primary-accent-color) 40%, transparent);
}

.estimate-log-badge-action-delete {
    background: color-mix(in srgb, #b85454 20%, transparent);
    border-color: color-mix(in srgb, #b85454 48%, transparent);
}

.estimate-log-badge-action-export {
    background: color-mix(in srgb, #907331 20%, transparent);
    border-color: color-mix(in srgb, #907331 48%, transparent);
}

.estimate-log-message {
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.45;
    word-break: break-word;
}

.estimate-logs-footer-left {
  display: flex;
  justify-content: flex-start;
}

.estimate-logs-footer-right {
  display: flex;
  justify-content: flex-end;
}

.project-updates-modal {
    width: 60vw !important;
    min-width: 600px;
    max-height: calc(100vh - 180px);
}

/* Header shows the project name; truncate with an ellipsis and leave room for the close X */
.project-updates-modal h2 {
    padding-right: 40px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.project-updates-modal.modal-two-tone {
    overflow: hidden;
}

.project-updates-modal.modal-two-tone .modal-form {
    max-height: calc(100vh - 220px);
    overflow: hidden;
    min-height: 0;
    grid-template-rows:
        minmax(0, 1fr)
        auto
        auto
        auto;
}

.project-updates-modal .project-updates-list {
    grid-column: 2;
    grid-row: 1;
    padding-top: 8px;
    min-height: 0;
    height: 100%;
    display: flex;
    overflow-y: auto;
    gap: 8px;
    overflow-x: hidden;
    padding-right: 8px;
    box-sizing: border-box;
    flex-direction: column;
}

.project-update-thread {
    display: flex;
    flex-direction: column;
}

.project-update-card {
    padding: 15px;
    border-radius: 5px;
    background: var(--sub-background-color);
}

/* Keeps the line breaks, blank lines and indentation the author typed in the composer. */
.project-update-card-body {
    white-space: pre-wrap;
    word-break: break-word;
}

/* Header lays out author, badges and time in a row so the menu button can sit at the far right.
   It wraps, so on a narrow panel the deleted note drops to its own line instead of squashing. */
.project-update-card-header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 8px;
}

.project-update-card-menu-btn {
    width: 24px;
    height: 24px;
    min-width: 24px !important;
    padding: 0 !important;
    margin-top: 0 !important;
    margin-left: auto;
    border: none;
    border-radius: 6px;
    background-color: transparent;
    background-image: url("/caddy/images/icons/menu/Dark Options.png");
    background-size: 14px 14px;
    background-repeat: no-repeat;
    background-position: center;
    cursor: pointer;
}

.project-update-card-menu-btn:hover {
    background-color: var(--secondary-accent-color);
}

/* Tombstone left behind by a deleted update, so a tagged reader can tell it was removed. It sits
   inline with the name and date, and moves to its own line only when the header has to wrap. */
.project-update-card-deleted {
    color: var(--font-color);
    font-style: italic;
    opacity: 0.75;
}

.project-update-card-edited {
    font-size: 0.75rem;
    font-style: italic;
    opacity: 0.7;
}

/* The shared context menu sits at z-index 2000, below the 9000 updates shell, so it needs to be
   lifted when it is opened from inside the updates modal. */
.admin-context-menu.project-update-card-menu {
    z-index: 12500;
}

/* Long updates scroll inside the edit box rather than stretching the modal off screen. */
.project-update-edit-text {
    max-height: 45vh;
    overflow-y: auto;
    resize: vertical;
    white-space: pre-wrap;
}

/* Row holding the edit box's @ button. */
.project-update-edit-tools {
    display: flex;
    align-items: center;
    gap: 8px;
}

.project-update-thread:has(.project-update-replies) > .project-update-card {
    border-bottom-right-radius: 0;
}

.project-update-replies {
    display: flex;
    flex-direction: column;
    gap: 0;
    margin-left: 26px;
    padding-left: 12px;
    border-left: 2px solid var(--accent-color);
    background: transparent;
}

.project-update-reply-card {
    padding: 12px;
    background: color-mix(in srgb, var(--sub-background-color) 70%, var(--background-color) 30%);
}

.project-update-reply-card:first-child {
    border-top-right-radius: 0;
}

.project-update-reply-card:last-child {
    border-bottom-right-radius: 5px;
    border-bottom-left-radius: 5px;
}

.project-update-reply-card + .project-update-reply-card {
    border-top: 1px solid var(--accent-color);
}

.project-update-inline-reply {
    margin-left: 26px;
    padding-left: 12px;
    border-left: 2px solid transparent;
}

.project-update-inline-reply-input {
    width: 100%;
    min-height: 38px !important;
    height: 38px;
    resize: none;
    overflow: hidden;
    box-sizing: border-box;
}

.project-update-inline-reply.is-active {
    border-left-color: var(--accent-color);
}

.project-update-inline-reply.is-active .project-update-inline-reply-input {
    min-height: 90px !important;
    height: 90px;
    resize: vertical;
    overflow-y: auto;
}

.project-update-inline-reply-actions {
    display: none;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 8px;
}

.project-update-inline-reply.is-active .project-update-inline-reply-actions {
    display: flex;
}

.project-update-inline-reply-actions button {
    min-width: auto !important;
    padding: 6px 12px !important;
    margin-top: 0 !important;
    font-size: 0.85rem;
}

/* Load older updates button, pinned above the oldest loaded thread */
.project-updates-load-more {
    display: flex;
    justify-content: center;
    padding: 4px 0 10px 0;
}

.project-updates-load-more-btn {
    min-width: auto;
    padding: 6px 14px;
    border: 1px solid var(--accent-color);
    border-radius: 5px;
    background: var(--sub-background-color);
    color: var(--text-color);
    font-size: 0.85rem;
    cursor: pointer;
}

.project-updates-load-more-btn:hover:not(:disabled) {
    background: color-mix(in srgb, var(--sub-background-color) 70%, var(--accent-color) 30%);
}

.project-updates-load-more-btn:disabled {
    opacity: 0.6;
    cursor: default;
}

.project-updates-modal textarea {
    max-height: 160px;
}

.project-updates-modal .project-button-row,
.project-updates-modal .cp-error {
    min-height: 0;
}

.project-update-compose-wrap {
  display: grid;
  grid-template-columns: 36px 1fr;
  align-items: start;
  gap: 8px;
  grid-column: 2;
}

/* Update vs Follow-up label tabs above the composer */
.project-update-label-toggle {
  grid-column: 2;
  display: inline-flex;
  gap: 0;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--accent-color);
}

.project-update-label-option {
  min-width: 0 !important;
  padding: 6px 18px !important;
  border: none !important;
  border-bottom: 3px solid transparent !important;
  border-radius: 0 !important;
  background: transparent !important;
  color: var(--font-color);
  opacity: 0.55;
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  margin-bottom: -1px;
}

.project-update-label-option:hover {
  opacity: 0.85;
}

.project-update-label-option.is-active {
  opacity: 1;
  font-weight: 700;
  color: var(--primary-accent-color);
  border-bottom-color: var(--primary-accent-color) !important;
}

/* Updates vs Communication tabs (only rendered when the caller enables communications) */
.project-updates-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--accent-color);
  background: 
    color-mix(in srgb, var(--sub-background-color) 78%, var(--background-color) 22%);
}

.project-updates-tab {
  min-width: 0 !important;
  padding: 8px 18px !important;
  border: none !important;
  border-bottom: 3px solid transparent !important;
  border-radius: 0 !important;
  background: transparent !important;
  color: var(--font-color);
  opacity: 0.6;
  font-size: 0.95rem;
  font-weight: 500;
  cursor: pointer;
  margin-bottom: -1px;
}

.project-updates-tab:hover {
  opacity: 0.9;
}

.project-updates-tab.is-active {
  opacity: 1;
  font-weight: 700;
  color: var(--primary-accent-color);
  border-bottom-color: var(--primary-accent-color) !important;
}

/* The panes share the updates list scroll cell; show one per active tab */
.project-updates-modal:not(.comm-tab-active) #project-communication-list {
  display: none !important;
}

.project-updates-modal:not(.info-tab-active) #project-info-list {
  display: none !important;
}

/* Communication tab active: hide the whole updates column and the info pane */
.project-updates-modal.comm-tab-active #project-updates-list,
.project-updates-modal.comm-tab-active #project-update-prev-label,
.project-updates-modal.comm-tab-active #project-update-compose-label,
.project-updates-modal.comm-tab-active .project-update-label-toggle,
.project-updates-modal.comm-tab-active .project-update-compose-wrap,
.project-updates-modal.comm-tab-active #project-updates-error,
.project-updates-modal.comm-tab-active .project-button-row {
  display: none !important;
}

/* Info tab active: hide the whole updates column (compose included) */
.project-updates-modal.info-tab-active #project-updates-list,
.project-updates-modal.info-tab-active #project-update-prev-label,
.project-updates-modal.info-tab-active #project-update-compose-label,
.project-updates-modal.info-tab-active .project-update-label-toggle,
.project-updates-modal.info-tab-active .project-update-compose-wrap,
.project-updates-modal.info-tab-active #project-updates-error,
.project-updates-modal.info-tab-active .project-button-row {
  display: none !important;
}

/* Checklist pane: hidden unless the Checklist tab is active */
.project-updates-modal:not(.checklist-tab-active) #project-checklist-list {
  display: none !important;
}

/* Checklist tab active: hide the whole updates column (compose included) */
.project-updates-modal.checklist-tab-active #project-updates-list,
.project-updates-modal.checklist-tab-active #project-update-prev-label,
.project-updates-modal.checklist-tab-active #project-update-compose-label,
.project-updates-modal.checklist-tab-active .project-update-label-toggle,
.project-updates-modal.checklist-tab-active .project-update-compose-wrap,
.project-updates-modal.checklist-tab-active #project-updates-error,
.project-updates-modal.checklist-tab-active .project-button-row {
  display: none !important;
}

/* Checklist tab: type dropdown header, then the question list */
.project-checklist-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.project-checklist-type-label {
  margin-top: 0 !important;
  color: var(--font-color);
}

.project-checklist-type {
  min-width: 220px;
}

/* Admin-only "Select all" in a checklist head; pushed to the right of the type dropdown */
.project-checklist-head > .checkout-select-all-btn {
  margin-left: auto;
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Read-only notice shown while a submitted sales checklist is in review (Checklist tab) */
.project-checklist-readonly-note {
  margin: 0 0 12px 0;
  color: var(--muted-font-color, var(--font-color));
  font-style: italic;
}

.project-checklist-body .checkout-questions {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Info tab: dashboard-style section cards that reflow into more columns as the panel widens.
   Cards stretch to a shared height per row so the bottoms line up instead of looking ragged. */
#project-info-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  align-content: start;
  align-items: stretch;
  gap: 14px;
}

.project-info-tip {
  grid-column: 1 / -1;
  margin: 0 2px;
  font-size: 12px;
  font-style: italic;
  opacity: 0.6;
}

.project-info-group {
  background: var(--sub-background-color);
  border-radius: 14px;
  padding: 14px 16px;
  box-shadow: 0 2px 5px var(--shadow);
}

.project-info-group-title {
  margin-bottom: 8px;
  padding-bottom: 8px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--secondary-color);
  border-bottom: 1px solid var(--other-color);
}

.project-info-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 14px;
  padding: 5px 0;
  border-bottom: 1px solid var(--accent-color);
}

.project-info-row:last-child {
  border-bottom: none;
}

.project-info-label {
  flex: 0 0 auto;
  color: var(--font-color);
  opacity: 0.65;
  font-size: 0.82rem;
}

.project-info-value {
  flex: 1 1 auto;
  text-align: right;
  color: var(--font-color);
  font-size: 0.88rem;
  font-weight: 600;
  word-break: break-word;
  white-space: pre-wrap;
}

/* One contact in an Info tab value. white-space resets the value's pre-wrap, which would otherwise
   render the markup's own line breaks as blank lines between the name and its details. */
.project-info-contact {
  display: block;
  white-space: normal;
}

.project-info-contact + .project-info-contact {
  margin-top: 8px;
}

.project-info-contact-name {
  display: block;
}

/* Email and phone under a name, lighter than the name so the name still leads */
.project-info-contact-line {
  display: block;
  color: var(--font-color);
  opacity: 0.75;
  font-size: 0.8rem;
  font-weight: 400;
  text-decoration: none;
  word-break: break-all;
}

.project-info-contact-line:hover {
  opacity: 1;
  text-decoration: underline;
}

/* The people attached to a company, stepped in under it */
.project-info-contact-people {
  margin-top: 4px;
}

.project-info-contact-person {
  margin-top: 6px;
  font-size: 0.84rem;
  font-weight: 500;
}

/* Linked Sales Actions block appended below the info cards (sales/admin only) */
.project-info-actions {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.project-info-divider {
  border-top: 1px solid var(--other-color);
  margin: 6px 0 4px;
}

.project-info-actions-title {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--secondary-color);
}

.project-info-action-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--sub-background-color);
  border-radius: 14px;
  padding: 12px 16px;
  box-shadow: 0 2px 5px var(--shadow);
}

.project-info-action-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}

.project-info-action-name {
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--font-color);
  word-break: break-word;
  margin-right: auto;
}

.project-info-action-followup {
  flex: 0 0 auto;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: #fff;
  background: var(--secondary-color);
  padding: 3px 10px;
  border-radius: 999px;
  white-space: nowrap;
}

/* Date/time the action was used to close the project follow-up, shown next to the badge */
.project-info-action-followup-at {
  flex: 0 0 auto;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--font-color);
  opacity: 0.7;
  white-space: nowrap;
}

/* Badge marking the action that created the project; green to read distinctly from Follow-up */
.project-info-action-created {
  flex: 0 0 auto;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: #fff;
  background: #3a7d5c;
  padding: 3px 10px;
  border-radius: 999px;
  white-space: nowrap;
}

/* Date/time the action was used to create the project, shown next to the badge */
.project-info-action-created-at {
  flex: 0 0 auto;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--font-color);
  opacity: 0.7;
  white-space: nowrap;
}

.project-info-action-status {
  flex: 0 0 auto;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--font-color);
  background: color-mix(in srgb, var(--secondary-color) 22%, transparent);
  padding: 3px 10px;
  border-radius: 999px;
  white-space: nowrap;
}

.project-info-action-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font-size: 0.82rem;
  opacity: 0.7;
}

/* Which discipline an assurance record covers, so two records on one project read apart. */
.project-info-assurance-disc {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--other-color);
  color: var(--secondary-color);
}

.project-info-assurance-disc.is-mech {
  color: var(--primary-color);
  border-color: var(--primary-accent-color);
}

/* The meta row carries its own opacity, and a child cannot climb back out of that, so the price
   sits beside the row rather than inside it and keeps full strength. */
.project-info-assurance-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 14px;
}

.project-info-assurance-price {
  flex: 0 0 auto;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--font-color);
  white-space: nowrap;
}

.project-info-action-link {
  align-self: flex-start;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--primary-color);
  text-decoration: none;
}

.project-info-action-link:hover {
  text-decoration: underline;
}

.project-communication-thread {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
  border: 1px solid var(--accent-color);
  border-radius: 8px;
}

.project-communication-subject {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  font-weight: 700;
}

/* Trashcan icon button; inherits the standard modal button base + hover. */
.project-communication-unlink {
  min-width: 0 !important;
  margin-top: 0 !important;
  padding: 5px 7px !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.project-communication-unlink:hover {
  background: var(--secondary-accent-color);
  border-color: var(--primary-accent-color);
}

.project-communication-unlink img {
  width: 16px;
  height: 16px;
  display: block;
}

/* Each email in the expanded thread is a distinct card: full border plus a left accent stripe so
   it's obvious where one message ends and the next begins. */
.project-communication-msg {
  padding: 10px 12px;
  border: 1px solid var(--accent-color);
  border-left: 3px solid var(--primary-accent-color);
  border-radius: 8px;
  background: rgba(127, 127, 127, 0.08);
}

.project-communication-meta {
  font-size: 0.82rem;
  color: var(--secondary-color);
}

/* Inside a message the sender/date reads as a header, divided from the body below. */
.project-communication-msg .project-communication-meta {
  font-weight: 600;
  padding-bottom: 6px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--accent-color);
}

/* Export-icon button that opens the email on Outlook web; matches the trash icon button (inherits
   the standard modal button border/background base). */
.project-communication-open {
  min-width: 0 !important;
  margin-top: 0 !important;
  padding: 5px 7px !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.project-communication-open:hover {
  background: var(--secondary-accent-color) !important;
  border-color: var(--primary-accent-color) !important;
}

.project-communication-open img {
  width: 16px;
  height: 16px;
  display: block;
}

/* Subject + expand toggle sit together on the left; the subject truncates first. */
.project-communication-subject-main {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  flex: 1;
}

.project-communication-subject-text {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Row under the subject: when it was linked. */
.project-communication-subline {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* When the email was linked to this project/action (not the email's own date). */
.project-communication-linked {
  font-weight: 400;
  font-size: 0.78rem;
  color: var(--secondary-color);
  white-space: nowrap;
}

.project-communication-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}

/* Expand toggle: looks like a standard button (inherits the base border/background), holds the
   same collapse arrow as the project expand cells. */
.project-communication-expand {
  min-width: 0 !important;
  margin: 0 !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex: 0 0 auto;
}

.project-communication-expand:hover {
  background: var(--secondary-accent-color) !important;
  border-color: var(--primary-accent-color) !important;
}

.project-communication-expand .collapse-icon {
  display: inline-block;
  width: 20px;
  height: 20px;
  background-image: url('/caddy/images/icons/collapse/light collapse.png');
  background-repeat: no-repeat;
  background-position: center;
  background-size: 30px 30px;
  transform: rotate(0deg);
  transition: transform 120ms ease;
}

.project-communication-thread.is-expanded .project-communication-expand .collapse-icon {
  transform: rotate(90deg);
}

/* Branded spinner shown while the thread loads live from Outlook. */
.project-communication-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
}

.project-communication-loading img {
  width: 40px;
  height: 40px;
  object-fit: contain;
}

/* Full saved thread; hidden until the row is expanded, then scrolls within a capped height. */
.project-communication-thread-body {
  display: none;
  flex-direction: column;
  gap: 8px;
  max-height: 720px;
  overflow-y: auto;
  margin-top: 2px;
  padding-right: 4px;
}

.project-communication-thread.is-expanded .project-communication-thread-body {
  display: flex;
}

/* Full plain-text message body fetched live on expand. */
.project-communication-body {
  margin-top: 4px;
  font-size: 0.9rem;
  white-space: pre-wrap;
  word-break: break-word;
}

.project-communication-error {
  font-size: 0.85rem;
  color: var(--secondary-color);
}

/* Always-visible square listing every attachment in the thread (shown only when there are files;
   JS toggles inline display:none when the thread has none). */
.project-communication-attach-panel {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 10px;
  border: 1px solid var(--accent-color);
  border-radius: 8px;
  background: rgba(127, 127, 127, 0.08);
}

.project-communication-attach-label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--secondary-color);
}

/* One attachment row: the file link plus the date/time of the email it came from. */
.project-communication-attach-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 8px;
}

.project-communication-attach-time {
  font-size: 0.75rem;
  color: var(--secondary-color);
}

/* Per-email attachment row: paperclip + the files on that message. */
.project-communication-attachments {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  margin-top: 6px;
}

.project-communication-clip {
  display: inline-flex;
  align-items: center;
  color: var(--secondary-color);
}

.project-communication-attachment {
  font-size: 0.85rem;
  color: var(--primary-accent-color);
  cursor: pointer;
}

.project-communication-attachment:hover {
  text-decoration: underline;
}

/* Pasted-screenshot thumbnails inside an email. */
.project-communication-images {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
  margin-bottom: 8px;
}

.project-communication-image {
  max-width: 200px;
  max-height: 150px;
  border: 1px solid var(--accent-color);
  border-radius: 6px;
  object-fit: cover;
  display: block;
  cursor: pointer;
}

/* Follow-up badge shown on update cards */
.project-update-badge {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.5;
}

.project-update-badge-followup {
  background: var(--secondary-color);
  color: #fff;
}

/* Link back to the sales action that produced an auto-created follow-up update */
.project-update-source-action {
  font-size: 0.8rem;
  color: var(--font-color);
  opacity: 0.75;
  margin: -2px 0 6px;
}

.project-update-source-action a {
  font-weight: 600;
  color: var(--primary-color);
  text-decoration: none;
}

.project-update-source-action a:hover {
  text-decoration: underline;
}

.project-updates-modal .cp-error,
.project-updates-modal .project-button-row {
  grid-column: 2;
}

.project-update-mention-btn {
  width: 36px;
  height: 36px;
  min-width: 36px !important;
  padding: 0 !important;
  margin-top: 5px !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  border-radius: 8px;
  border: 1px solid var(--accent-color);
  background: var(--sub-background-color);
  color: var(--primary-color);
  font-weight: 800;
  cursor: pointer;
}

.project-update-mention-btn:hover {
  background: var(--secondary-accent-color);
}

.project-update-mention-btn {
  margin-top: 10px !important;
}

.project-update-mention-menu {
  position: fixed;
  max-height: 260px;
  overflow-y: auto;
  border: 1px solid var(--accent-color);
  border-radius: 10px;
  background: var(--background-color);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.22);
  z-index: 9000;
  padding: 6px;
}

.project-update-mention-option {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
  color: var(--font-color);
}

.project-update-mention-option:hover,
.project-update-mention-option.is-active {
  background: var(--secondary-accent-color);
}

.project-update-mention-option-name {
  font-weight: 700;
}

.project-update-mention-option-email {
  font-size: 0.78rem;
  opacity: 0.75;
}

.project-update-mention-empty {
  padding: 8px 10px;
  opacity: 0.75;
}

.project-update-mention {
  display: inline-flex;
  align-items: center;
  border: none !important;
  background: color-mix(in srgb, var(--primary-color) 14%, transparent);
  color: var(--primary-color) !important;
  padding: 1px 2px !important;
  font: inherit;
  margin-top: 0 !important;
  cursor: default !important;
}

.project-update-mention:hover {
  background: color-mix(in srgb, var(--primary-color) 24%, transparent);
}

.project-update-link {
  color: var(--primary-color);
  text-decoration: underline;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.project-update-link:hover {
  text-decoration: none;
}

.edit-admin-item-prices-item-label {
    padding: 10px 12px;
    font-weight: 700;
    overflow-wrap: anywhere;
}

.modal-content button:disabled,
.modal-content button.is-saving {
    opacity: 0.45;
    cursor: not-allowed !important;
    filter: grayscale(0.7);
    pointer-events: auto;
}

.modal-content button:disabled:hover,
.modal-content button.is-saving:hover {
    border-color: var(--secondary-accent-color) !important;
    background-color: var(--sub-background-color);
}

.caddy-tooltip {
    position: fixed;
    z-index: 100001;
    max-width: 320px;
    padding: 7px 9px;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--background-color);
    color: var(--font-color);
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.28);
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.35;
    pointer-events: none;
    white-space: normal;
    overflow-wrap: anywhere;
}

.caddy-tooltip-body {
    white-space: pre-line;
}

.caddy-tooltip-body + .caddy-tooltip-note,
.caddy-tooltip-pair + .caddy-tooltip-note {
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid var(--accent-color);
}

.caddy-tooltip-note {
    font-style: italic;
    font-weight: 500;
    opacity: 0.82;
}

.caddy-tooltip.hidden {
    display: none !important;
}
/* Shared right-click context menu (same look as the projects/admin pages, made
   available everywhere via modals.css so non-admin pages can use it too). */
.admin-context-menu {
    position: fixed;
    z-index: 2000;
    min-width: 160px;
    padding: 6px;
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    background: var(--background-color);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.22);
}
.admin-context-menu.hidden {
    display: none !important;
}
.admin-context-menu-btn {
    display: flex;
    width: 100%;
    align-items: center;
    justify-content: flex-start;
    padding: 8px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--font-color);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.9rem;
}
.admin-context-menu-btn:hover {
    background: var(--sub-background-color);
}
.admin-context-menu-btn-danger:hover {
    background: color-mix(in srgb, var(--bad, #991b1b) 14%, transparent);
}
/* Larger, distinct variant (opt-in via data-tooltip-size="lg"): same background
   as other tooltips, but a clear accent outline and structured value pairs. */
.caddy-tooltip.caddy-tooltip-lg {
    max-width: 380px;
    padding: 12px 14px;
    font-size: 14px;
    line-height: 1.5;
    border: 1px solid var(--primary-accent-color);
    border-radius: 10px;
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.34);
}
/* Label/value pairs: small uppercase label over a prominent value, divided. */
.caddy-tooltip-pair {
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.caddy-tooltip-pair + .caddy-tooltip-pair {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--accent-color);
}
.caddy-tooltip-pair-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    opacity: 0.65;
}
.caddy-tooltip-pair-value {
    font-size: 14.5px;
    font-weight: 600;
}
.ces-breakout-checkbox-cell {
    display: flex;
    align-items: center;
    min-height: 52px;
    padding: 0 18px;
    margin-left: -10px;
    box-sizing: border-box;
}

.ces-breakout-checkbox-row {
    display: inline-flex !important;
    align-items: center;
    gap: 10px;
    margin: 0 !important;
    padding: 0 !important;
    min-height: 0 !important;
    font-weight: 600;
    cursor: pointer;
}

.ces-breakout-checkbox-row input[type="checkbox"] {
    min-width: 18px !important;
    width: 18px;
    height: 18px;
    margin: 0;
    padding: 0;
}

/* Company-wide toggle in the Add Assembly modal. Mirrors the breakout checkbox cell so it sits
   in the two-tone grid's value column, and resets the global .modal-content input min-width. */
.create-package-company-wide-cell {
    display: flex;
    align-items: center;
    min-height: 52px;
    padding: 0 18px;
    margin-left: -10px;
    box-sizing: border-box;
}

.create-package-company-wide-row {
    display: inline-flex !important;
    align-items: center;
    gap: 10px;
    margin: 0 !important;
    padding: 0 !important;
    min-height: 0 !important;
    font-weight: 600;
    cursor: pointer;
}

.create-package-company-wide-row input[type="checkbox"] {
    min-width: 18px !important;
    width: 18px;
    height: 18px;
    margin: 0;
    padding: 0;
}

.invite-details-modal {
    width: min(720px, 92vw) !important;
}

.invite-details-modal .invite-details-form {
    grid-template-columns: 180px minmax(0, 1fr);
}

.invite-details-value {
    min-height: 52px;
    padding: 14px 18px;
    box-sizing: border-box;
    overflow-wrap: anywhere;
    /* font-weight: 700; */
    color: var(--font-color);
}

.invite-details-token {
    font-family: Consolas, monospace;
    font-size: 0.86rem;
    line-height: 1.5;
}

.invite-details-status {
    display: inline-flex;
    align-items: center;
    min-height: 28px;
    padding: 3px 10px;
    border-radius: 999px;
    border: 1px solid var(--accent-color);
    background: var(--sub-background-color);
    font-size: 0.85rem;
    font-weight: 800;
}

.invite-documents-modal {
    width: min(720px, 92vw) !important;
}

.invite-documents-list {
    padding: 14px 18px;
    max-height: calc(100vh - 420px);
}

.invite-documents-sent {
    padding: 14px 18px;
    opacity: 0.85;
}

.invite-documents-button-row {
    grid-column: 2;
}

/* Read-only invite note view */
.invite-note-modal {
    width: min(620px, 92vw) !important;
}

.invite-note-text {
    padding: 14px 18px;
    line-height: 1.55;
    overflow-wrap: anywhere;
}

.invite-note-sent {
    padding: 14px 18px;
    opacity: 0.85;
}

.invite-logs-modal {
    width: min(760px, 92vw) !important;
}

.invite-logs-modal.modal-two-tone {
    overflow: hidden;
}

.invite-logs-modal.modal-two-tone .invite-logs-form {
    height: calc(100vh - 350px);
    overflow-y: auto;
    grid-template-rows:
        minmax(260px, 1fr)
        auto;
}

.invite-logs-panel {
    min-height: 260px;
    padding: 14px 18px;
    box-sizing: border-box;
}

.invite-logs-list {
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 460px);
    overflow-y: auto;
    padding-right: 8px;
    box-sizing: border-box;
}

.invite-log-row:last-child {
    border-bottom: none;
}

.invite-log-title {
    font-weight: 800;
    color: var(--font-color);
    font-size: 1rem;
}

.invite-log-detail {
    margin-top: 4px;
    opacity: 0.86;
    line-height: 1.35;
}

.invite-log-meta {
    margin-top: 5px;
    font-size: 0.86rem;
    opacity: 0.7;
}

.invite-logs-loading,
.invite-logs-empty {
    padding: 18px;
    border: 1px dashed var(--accent-color);
    border-radius: 10px;
    text-align: center;
    opacity: 0.75;
}

.invite-logs-button-row {
    grid-column: 2;
}

.invite-logs-list {
    scrollbar-width: thin;
    scrollbar-color: var(--sub-background-color) var(--background-color);
}

.invite-logs-list::-webkit-scrollbar {
    width: 12px;
}

.invite-logs-list::-webkit-scrollbar-track {
    background: var(--background-color);
    border-radius: 6px;
}

.invite-logs-list::-webkit-scrollbar-thumb {
    background: var(--sub-background-color);
    border-radius: 6px;
    border: 2px solid var(--background-color);
}

.invite-logs-list::-webkit-scrollbar-thumb:hover {
    background: var(--accent-color);
}

.admin-sub-locations-modal-form {
    position: relative;
}

.admin-sub-locations-meta-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-top: 8px;
    margin-right: 10px;
}

.admin-sub-locations-contact-name {
    font-weight: 700;
    opacity: 0.85;
}

.admin-sub-locations-add-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    min-width: 34px !important;
    padding: 0 !important;
    margin: 0 !important;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--sub-background-color);
    color: var(--font-color);
    font-size: 1.2rem;
    font-weight: 800;
    line-height: 1;
    cursor: pointer;
}

.admin-sub-locations-add-btn:hover {
    background: color-mix(in srgb, var(--secondary-accent-color) 55%, var(--sub-background-color));
}

.admin-sub-locations-add-icon {
    content: url("/caddy/images/icons/add/light mode plus icon.png");
    width: 18px;
    height: 18px;
    display: block;
    margin: 0;
    pointer-events: none;
}

.admin-sub-locations-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: 100%;
    min-width: 0;
}

.admin-sub-location-row {
    display: flex;
    gap: 10px;
    min-width: 0;
    padding: 10px;
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    background: var(--sub-background-color);
    flex-wrap: nowrap;
    justify-content: flex-start;
    flex-direction: row;
    align-items: center;
}

.admin-sub-location-row label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.admin-sub-location-row label:nth-of-type(2) {
    flex: 0 0 220px;
    width: 220px;
}

/* City → Zip cascade columns (override the positional widths above; wrap on narrow widths) */
.admin-sub-location-row {
    flex-wrap: wrap;
}

.admin-sub-location-row label.admin-sub-loc-zip,
.admin-sub-location-row label.admin-sub-loc-newcity,
.admin-sub-location-row label.admin-sub-loc-newzip {
    flex: 0 0 160px;
    width: 160px;
}

.admin-sub-location-row input,
.admin-sub-location-row select {
    max-width: 50px;
    min-width: 0 !important;
    box-sizing: border-box;
}

/* Title rows: the "New Title" column flexes to fill the row and its input is full width. */
.admin-sub-location-row label.admin-sub-loc-newtitle {
    flex: 1 1 220px;
    width: auto;
}
.admin-sub-location-row label.admin-sub-loc-newtitle input {
    max-width: 300px;
    width: 100%;
}

.admin-sub-location-remove {
    display: inline-flex;
    justify-content: center;
    margin-left: auto !important;
    width: 30px;
    height: 30px;
    min-width: 30px !important;
    background: var(--background-color);
    align-items: center;
}

.admin-sub-location-remove:hover {
    background: color-mix(in srgb, var(--secondary-accent-color) 45%, var(--background-color));
}

.admin-sub-location-remove-icon {
    content: url("/caddy/images/icons/trashcan/Light Trashcan.png");
    width: 16px;
    height: 16px;
    display: block;
    margin: 0;
    pointer-events: none;
}

.admin-sub-locations-empty {
    opacity: 0.72;
    font-style: italic;
}

.admin-sub-location-radius {
    margin-top: 0 !important;
}

/* Location rows inside the narrower "Add Contact" create modal: let the location
   dropdown flex to fill the row and keep the radius column compact so the row fits
   the standard modal width instead of the wide manage-locations modal. */
#create-admin-sub-locations-list .admin-sub-location-row {
    padding: 8px;
}

#create-admin-sub-locations-list .admin-sub-location-row label:nth-of-type(2) {
    min-width: 110px;
}

/* ===== Add Subcontractor picker modal ===== */
/* People checklist, styled like the create modal's roles list so it reads as a
   normal two-tone modal control sitting in the right (content) column. */
.modal-content .sub-picker-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 8px 0;
    padding: 6px;
    max-height: 320px;
    overflow-y: auto;
    border: 1px solid color-mix(in srgb, var(--font-color) 18%, transparent);
    border-radius: 8px;
}

.modal-content .sub-picker-row {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    margin: 0;
    padding: 9px 11px;
    border-radius: 6px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.12s ease;
}

.modal-content .sub-picker-row:hover {
    background-color: color-mix(in srgb, var(--font-color) 8%, transparent);
}

.modal-content .sub-picker-row:has(.sub-picker-check:checked) {
    background-color: var(--accent-color);
}

/* Reset the global ".modal-content input" min-width:96.5% so the checkbox renders
   as a normal small box inline to the left of the person's details. */
.modal-content .sub-picker-row .sub-picker-check {
    flex: 0 0 auto;
    width: 16px;
    min-width: 16px;
    height: 16px;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    background-color: transparent !important;
    accent-color: var(--accent-color-strong, var(--accent-color));
    cursor: pointer;
}

.sub-picker-row-main {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    text-align: left;
}

.sub-picker-row-name {
    font-weight: 600;
}

.sub-picker-row-meta {
    font-size: 0.8rem;
    opacity: 0.75;
}

.sub-picker-empty {
    opacity: 0.72;
    font-style: italic;
    padding: 12px;
}

/* "Only contacts at subcontractor companies" checkbox row (People tab). The inner label
   holds the checkbox + text inline; the width reset undoes the global input min-width. */
.sub-picker-sub-toggle {
    display: flex;
    align-items: center;
}

.sub-picker-sub-toggle > label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    cursor: pointer;
    font-weight: 500;
}

.modal-content .sub-picker-sub-toggle input[type="checkbox"] {
    width: 16px;
    min-width: 16px;
    height: 16px;
    margin: 0;
    padding: 0;
    accent-color: var(--accent-color-strong, var(--accent-color));
    cursor: pointer;
}

/* List cell wraps the scrollable list plus its pager as one grid control-column item. */
.sub-picker-list-cell {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* Prev / page label / Next row under each paginated list. */
.sub-picker-pager {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 6px;
}

.sub-picker-pager-label {
    font-size: 0.8rem;
    opacity: 0.8;
}

.modal-content .sub-picker-pager-btn {
    margin: 0;
    padding: 4px 12px;
    font-size: 0.8rem;
    font-weight: 600;
    border: 1px solid color-mix(in srgb, var(--font-color) 18%, transparent);
    border-radius: 6px;
    background: transparent;
    color: var(--font-color);
    cursor: pointer;
}

.modal-content .sub-picker-pager-btn:not(:disabled):hover {
    background: color-mix(in srgb, var(--font-color) 8%, transparent);
}

.modal-content .sub-picker-pager-btn:disabled {
    opacity: 0.45;
    cursor: default;
}

/* Selected people shown as removable chips below the list. */
.modal-content .sub-picker-selected {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 8px 0;
    min-width: 0;
}

.sub-picker-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 6px 4px 10px;
    border-radius: 14px;
    font-size: 0.82rem;
    font-weight: 500;
    background: var(--accent-color);
    color: var(--font-color);
}

.sub-picker-chip-name {
    line-height: 1;
}

/* Reset the global ".modal-content button" sizing so the remove control is a small round x. */
.modal-content .sub-picker-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    min-width: 16px;
    height: 16px;
    padding: 0;
    margin: 0;
    border: none;
    border-radius: 50%;
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
    background: color-mix(in srgb, var(--font-color) 16%, transparent);
    color: var(--font-color);
}

.modal-content .sub-picker-chip-remove:hover {
    background: color-mix(in srgb, var(--font-color) 30%, transparent);
}

/* Footer keeps the selected-count on the left, Cancel/Add on the right. */
.modal-content.modal-two-tone .modal-form > .sub-picker-footer {
    align-items: center;
}

.sub-picker-count {
    margin-right: auto;
    font-size: 0.85rem;
    opacity: 0.8;
}

/* People / Companies segmented toggle. The .sub-picker-mode-cell is the grid item (the
   two-tone rule forces it full width); the toggle pill inside is inline-flex so it hugs
   its two buttons and left-aligns instead of stretching the whole control column. */
.sub-picker-mode-toggle {
    display: inline-flex;
    gap: 0;
    border: 1px solid color-mix(in srgb, var(--font-color) 18%, transparent);
    border-radius: 8px;
    overflow: hidden;
    width: fit-content;
}

.modal-content .sub-picker-mode-btn {
    margin: 0;
    padding: 7px 16px;
    border: none;
    border-radius: 0;
    font-weight: 600;
    cursor: pointer;
    background: transparent;
    color: var(--font-color);
}

.modal-content .sub-picker-mode-btn.active {
    background: var(--accent-color);
}

/* Show only the active mode's rows (labels, inputs, and lists). The full two-tone prefix
   is needed so this beats the `.modal-form > label { display: flex }` rule above. */
.modal-content.modal-two-tone .modal-form[data-mode="people"] .sub-picker-companies-only,
.modal-content.modal-two-tone .modal-form[data-mode="companies"] .sub-picker-people-only {
    display: none;
}

/* The Company/Location/Zip selects are enhanced into a .custom-dropdown wrapper that does
   not carry the mode class, so hide the wrapper by the class on the select it holds. */
.modal-content.modal-two-tone .modal-form[data-mode="people"] .custom-dropdown:has(> .sub-picker-companies-only),
.modal-content.modal-two-tone .modal-form[data-mode="companies"] .custom-dropdown:has(> .sub-picker-people-only) {
    display: none;
}

/* ===== Project multi-contact rows (create/edit + dedicated editor) ===== */
.pc-add-contact-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-top: 0 !important;
    width: 32px;
    height: 32px;
    min-width: 32px !important;
    padding: 0 !important;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--sub-background-color);
    cursor: pointer;
}

.pc-add-contact-btn:hover:not(:disabled) {
    background: color-mix(in srgb, var(--secondary-accent-color) 55%, var(--sub-background-color));
}

.pc-add-contact-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.pc-add-contact-icon {
    content: url("/caddy/images/icons/add/light mode plus icon.png");
    width: 18px;
    height: 18px;
    display: block;
    pointer-events: none;
}

.pc-contacts-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: 100%;
    min-width: 0;
}

/* Role-grouped contact sections (Bidders / Engineers / Owners). */
.pc-role-sections {
    gap: 18px;
}

.pc-role-section {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    min-width: 0;
}

/* Hidden role section. Needed because .pc-role-section sets display:flex, which would otherwise
   win over a bare .hidden utility. */
.pc-role-section.hidden {
    display: none !important;
}

.pc-role-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 0 6px;
}

.pc-role-section-title {
    font-weight: 700;
    font-size: 0.95rem;
}

.pc-role-section-hint {
    font-weight: 400;
    font-size: 0.85rem;
    opacity: 0.7;
    margin-left: 4px;
}

.pc-contact-row {
    display: grid;
    grid-template-columns: 140px minmax(0, 1fr);
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    overflow: hidden;
    background: var(--sub-background-color);
}

.pc-contact-row-header {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--accent-color);
    background: color-mix(in srgb, var(--sub-background-color) 78%, var(--background-color) 22%);
}

.pc-contact-row-title {
    font-weight: 700;
}

.pc-contact-row > label {
    padding: 10px 14px;
    box-sizing: border-box;
    font-size: 0.9rem;
    margin-top: 0;
}

.pc-contact-row > input,
.pc-contact-row > .custom-dropdown {
    grid-column: 2;
    align-self: center;
    min-width: 0;
    background: none !important;
    box-sizing: border-box;
    margin: 6px 10px 6px 0;
}

.pc-contact-row > input {
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    min-height: 40px;
    background: var(--background-color) !important;
    padding: 8px 12px;
    font-size: 0.9rem;
    color: var(--font-color);
}

.pc-contact-row > .custom-dropdown {
    width: calc(100% - 10px);
}

.pc-contact-row .custom-dropdown-trigger {
    width: 100%;
    min-height: 40px;
    height: 40px;
    padding: 0 32px 0 12px;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
}

/* Ensure hidden labels and fields collapse their grid row */
.pc-contact-row > .hidden,
.pc-contact-row > .custom-dropdown.hidden {
    display: none !important;
}

/* Winning bidder checkmark (Bidder company cards only): checkbox left, label right, in the card header.
   Overrides the global .modal-content input min-width/background so the box stays small. */
.modal-content label.pc-winning-bidder-option {
    flex: 0 0 auto;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    padding: 0;
    margin: 0;
    font-weight: 400;
    cursor: pointer;
}

.modal-content label.pc-winning-bidder-option input[type="checkbox"] {
    flex: 0 0 auto;
    width: 16px;
    min-width: 16px;
    height: 16px;
    min-height: 0;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    background: transparent !important;
    background-color: transparent !important;
    accent-color: var(--accent-color-strong, var(--accent-color));
}

.modal-content label.pc-winning-bidder-option span {
    flex: 1 1 auto;
    text-align: left;
    font-size: 0.9rem;
    white-space: nowrap;
}

/* Primary salesperson radio: sits in the card header next to the "Salesperson N" title. The title
   takes the free space so this stays beside the remove button rather than floating in the middle.
   Overrides the global .modal-content input min-width/background so the dot stays small. */
.pc-contact-row-header .pc-contact-row-title {
    flex: 1 1 auto;
}

.pc-contact-row-header label.pc-primary-option {
    flex: 0 0 auto;
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: 6px;
    padding: 0;
    margin: 0;
    font-weight: 400;
    cursor: pointer;
}

.pc-contact-row-header label.pc-primary-option input[type="radio"] {
    flex: 0 0 auto;
    width: 15px;
    min-width: 15px;
    height: 15px;
    min-height: 0;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent !important;
    background-color: transparent !important;
    /* Same palette purple the admin pages paint their checkboxes with. */
    accent-color: var(--primary-color);
    cursor: pointer;
}

.pc-contact-row-header label.pc-primary-option span {
    font-size: 0.85rem;
    white-space: nowrap;
}

/* Checked reads as the credited row, so the label firms up with it. */
.pc-contact-row-header label.pc-primary-option:has(input[type="radio"]:checked) span {
    font-weight: 700;
    color: var(--primary-color);
}

/* A read-only list still has to show who is credited, just not offer to change it. */
.pc-contact-row-header label.pc-primary-option input[type="radio"]:disabled {
    cursor: default;
}

.pc-contact-row-header label.pc-primary-option:has(input[type="radio"]:disabled) {
    cursor: default;
    opacity: 0.75;
}

/* Static "Primary" tag on a locked row, where the projects page shows a radio. Matches the weight and
   color of that radio's checked label so the same fact reads the same way on both pages. */
.pc-contact-row-header .pc-primary-badge {
    flex: 0 0 auto;
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--primary-color);
    white-space: nowrap;
    cursor: default;
}

/* A locked row (the primary salesperson on a commission split) has no remove button and a fixed
   person picker. Only its share is editable, so the fixed picker should read as a label rather than as
   a broken control: keep it legible instead of dimming it the way a genuinely disabled field is. */
.pc-contact-row-locked .custom-dropdown.is-disabled {
    opacity: 1;
}

.pc-contact-row-locked .custom-dropdown.is-disabled .custom-dropdown-trigger {
    cursor: default;
    opacity: 0.9;
}

.pc-contact-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    min-width: 28px !important;
    padding: 16px !important;
    margin: 0 !important;
    border: 1px solid var(--accent-color);
    border-radius: 6px;
    background: var(--background-color) !important;
    cursor: pointer;
    font-size: 1.1rem;
    border: none !important;
    line-height: 1;
}

.pc-contact-remove:hover {
    background: color-mix(in srgb, var(--secondary-accent-color) 55%, var(--sub-background-color)) !important;
}

/*  Project contact company cards (create project + role contacts modal)  */

/* Text add buttons ("+ Add company", "+ Add person"). The global modal button rule outranks a class, so the offsets need !important. */
.modal-content .pc-card-add-btn {
    flex: 0 0 auto;
    margin-top: 0 !important;
    min-width: 0 !important;
    padding: 6px 12px !important;
    font-size: 0.85rem;
    white-space: nowrap;
}

.pc-card-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: 100%;
    min-width: 0;
}

.pc-card-empty {
    padding: 4px 6px;
    font-size: 0.85rem;
    font-style: italic;
    opacity: 0.7;
}

.pc-card-empty.hidden,
.pc-card-field.hidden,
.pc-card-person-new.hidden {
    display: none !important;
}

.pc-card {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    overflow: hidden;
    background: var(--sub-background-color);
    min-width: 0;
}

.pc-card-header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 10px 8px 14px;
    border-bottom: 1px solid var(--accent-color);
    background: color-mix(in srgb, var(--sub-background-color) 78%, var(--background-color) 22%);
}

.pc-card-title {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: 700;
}

.pc-card-body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px 14px 12px;
    min-width: 0;
}

.pc-card-field {
    display: grid;
    grid-template-columns: 150px minmax(0, 1fr);
    align-items: center;
    gap: 6px 12px;
    min-width: 0;
}

.pc-card-label {
    font-size: 0.9rem;
    font-weight: 600;
}

/* Inputs fit their cell instead of the global 96.5% min width. */
.modal-content .pc-card-field input:not([type="checkbox"]):not([type="radio"]) {
    width: 100%;
    min-width: 0;
    min-height: 40px;
    margin: 0;
    box-sizing: border-box;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
}

.pc-card .custom-dropdown {
    width: 100%;
    min-width: 0;
}

.pc-card .custom-dropdown-trigger {
    width: 100%;
    min-height: 40px;
    height: 40px;
    padding: 0 32px 0 12px;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
}

.pc-card-people {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 4px;
    padding-top: 10px;
    border-top: 1px dashed var(--accent-color);
}

.pc-card-people-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.pc-card-people-title {
    font-size: 0.9rem;
    font-weight: 600;
}

.pc-card-people-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
}

.pc-card-person {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px 10px;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--background-color);
    min-width: 0;
}

.pc-card-person-row {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.pc-card-person-row > .custom-dropdown {
    flex: 1 1 auto;
}

.pc-card-person-row > .pc-contact-remove {
    flex: 0 0 auto;
}

.pc-card-person-new {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* The role contacts modal body is one full width column, not the label and field grid. */
.modal-content.modal-two-tone .modal-form.pc-role-modal-form {
    display: block;
    padding: 0;
    background: color-mix(in srgb, var(--background-color) 88%, black 12%);
}

.pc-role-modal-body {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 16px 18px;
    min-width: 0;
}

.modal-content.modal-two-tone .modal-form.pc-role-modal-form > .cp-error {
    margin: 0 18px 12px;
}

/*  Project role contacts, read only view  */

.pc-view-list {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.pc-view-block {
    display: grid;
    grid-template-columns: 130px minmax(0, 1fr);
    align-items: center;
    gap: 6px 12px;
    padding: 12px 14px;
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    background: var(--sub-background-color);
}

.pc-view-title {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    font-weight: 600;
    font-size: 1.02rem;
    margin-bottom: 2px;
}

.pc-view-name {
    overflow-wrap: anywhere;
}

.pc-view-badge {
    padding: 1px 8px;
    border-radius: 9px;
    font-size: 0.72rem;
    font-weight: 600;
    background: var(--secondary-accent-color, #d23f3f);
    color: #fff;
}

.pc-view-label {
    font-size: 0.85rem;
    opacity: 0.75;
}

.pc-view-value {
    padding: 2px 0;
    overflow-wrap: anywhere;
}

.pc-view-link {
    color: var(--primary-color);
    text-decoration: none;
    overflow-wrap: anywhere;
}

.pc-view-link:hover {
    text-decoration: underline;
}

.pc-view-missing {
    font-style: italic;
    opacity: 0.6;
}

.pc-view-people {
    grid-column: 1 / -1;
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 6px;
    padding-top: 10px;
    border-top: 1px dashed var(--accent-color);
}

.pc-view-person {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px 10px;
    border-radius: 8px;
    background: var(--background-color);
}

.pc-view-person-name {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.pc-view-person-title {
    margin-left: 8px;
    font-size: 0.85rem;
    font-weight: 400;
    opacity: 0.75;
}

.pc-view-person-contact {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 18px;
    font-size: 0.9rem;
}

.pc-view-person-item {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    min-width: 0;
}

.pc-view-inline-label {
    font-size: 0.8rem;
    opacity: 0.7;
}

.pc-view-people-empty,
.pc-view-empty {
    padding: 6px 2px;
    font-style: italic;
    opacity: 0.75;
}

/* Unlinked people: no company yet, so the block reads apart and each person gets a company picker. */
.pc-view-unlinked {
    border-style: dashed;
}

.pc-view-unlinked-note {
    grid-column: 1 / -1;
    font-size: 0.88rem;
    opacity: 0.8;
}

.pc-view-unlinked-pick {
    margin-top: 4px;
    max-width: 420px;
}

.pc-view-unlinked-actions {
    grid-column: 1 / -1;
    display: flex;
    justify-content: flex-end;
    margin-top: 4px;
}

/* Phones: stack the label and field grids and let the header wrap under the title. */
@media (max-width: 768px) {
    .pc-card-field,
    .pc-view-block {
        grid-template-columns: minmax(0, 1fr);
    }

    .pc-card-header {
        flex-wrap: wrap;
    }

    .pc-card-people-header {
        flex-wrap: wrap;
    }

    .pc-role-modal-body {
        padding: 12px;
    }

    .pc-view-person-contact {
        flex-direction: column;
    }
}

.project-person-badge-overflow {
    cursor: pointer;
    background: var(--sub-background-color);
    color: var(--text-color);
}

/* --- Project checkout modal (Ready for Review) --- */
/* Subhead spans both two-tone columns: project name on the left, the owner /
   estimate meta pushed to the right edge, both on the same baseline. */
.modal-content.modal-two-tone .modal-form > .checkout-subhead {
    grid-column: 1 / -1;
    display: flex;
    gap: 1rem;
    background: transparent;
    box-sizing: border-box;
    padding: 0px 18px;
    justify-content: space-between;
    align-items: baseline;
    margin: 8px 0px;
}

.checkout-subhead-meta {
    text-align: right;
    opacity: 0.85;
    /* Confine the meta to the two-tone right (controls) column, the full width minus the
       220px label column and the 10px grid gap — so it wraps within the right side of the
       modal rather than stretching across the whole modal toward the project name.
       (It's a flex child, so it's blockified and max-width applies.) */
    min-width: 0;
    /* max-width: calc(100% - 200px); */
    overflow-wrap: anywhere;
}

/* Read-only checkout view: render the meta on its own lines (context, then submission). */
.checkout-subhead-meta-line {
    display: block;
}

/* "Approved by ... on ..." line at the top of the read-only checkout view. */
.checkout-subhead-meta-line.checkout-approved-line {
    font-weight: 700;
    color: color-mix(in srgb, #27ae60 80%, var(--font-color));
}

/* Save-mode subhead right group: estimate meta + the "Clear All" button, far right. */
.checkout-subhead-right {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
    min-width: 0;
    max-width: calc(100% - 200px);
    align-items: baseline;
}

.checkout-subhead-right > .checkout-clear-btn {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* Left ("label") column of the two-tone grid: section heading + helper text. */
.modal-content.modal-two-tone .modal-form > .checkout-side {
    grid-column: 1;
    background: transparent;
    box-sizing: border-box;
    padding: 16px 18px;
    min-width: 0;
}

.checkout-side h3 {
    margin: 0;
    font-size: 1.05rem;
}

.checkout-side-note {
    margin: 0.4rem 0 0 0;
    font-size: 0.82rem;
    opacity: 0.75;
    line-height: 1.35;
}

/* Admin-only "Select all" under the Questions heading on the estimate checkout sheet */
.checkout-side > .checkout-select-all-btn {
    margin-top: 0.6rem;
    white-space: nowrap;
}

/* Right ("content") column: questions list / lesson cards. */
.modal-content.modal-two-tone .modal-form > .checkout-pane {
    box-sizing: border-box;
}

.checkout-question {
    margin-bottom: 0.6rem;
}

.checkout-question:last-child {
    margin-bottom: 0;
}

/* Opens the question's reference image in a viewer. Sized to match the note button it
   sits beside. Dark variant in palette.css. */
/* min-width/padding beat the generic ".modal-content button" rule, same as the note button. */
.checkout-question-image {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    min-width: 28px !important;
    margin: 0;
    padding: 0 !important;
    border-radius: 8px;
    border: 1px solid var(--accent-color);
    background-color: var(--sub-background-color);
    background-image: url("/caddy/images/icons/share/share-light.png");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 15px 15px;
    cursor: pointer;
}

.checkout-question-image:hover {
    background-color: var(--secondary-accent-color);
}

/* Image viewer overlay. Owns its own element rather than #caddyModal, which the
   checklist it was opened from is usually already using. */
.cb-image-viewer {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    background: rgba(0, 0, 0, 0.65);
}

.cb-image-viewer-panel {
    display: flex;
    flex-direction: column;
    max-width: min(1100px, 100%);
    max-height: 100%;
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    background: var(--background-color);
}

.cb-image-viewer-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.4rem;
    padding: 0.5rem 0.6rem;
    border-bottom: 1px solid var(--accent-color);
}

.cb-image-viewer-open {
    width: 28px;
    height: 28px;
    border-radius: 8px;
    border: 1px solid var(--accent-color);
    background-color: var(--sub-background-color);
    background-image: url("/caddy/images/icons/share/share-light.png");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 15px 15px;
    cursor: pointer;
}

.cb-image-viewer-open:hover {
    background-color: var(--secondary-accent-color);
}

.cb-image-viewer-close {
    width: 28px;
    height: 28px;
    min-width: 28px;
    margin: 0;
    padding: 0;
    border-radius: 8px;
    border: 1px solid var(--accent-color);
    background: var(--sub-background-color);
    color: var(--font-color);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}

.cb-image-viewer-close:hover {
    background: var(--secondary-accent-color);
}

.cb-image-viewer-body {
    overflow: auto;
    padding: 0.75rem;
}

.cb-image-viewer-body img {
    display: block;
    max-width: 100%;
    max-height: calc(100vh - 10rem);
    margin: 0 auto;
}

/* Small "Questions for: X" divider above a company's or subcontractor's questions. */
.checklist-group-label {
    margin: 0.9rem 0 0.35rem;
    padding-bottom: 0.2rem;
    border-bottom: 1px solid var(--font-color);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--font-color);
    opacity: 0.65;
}

/* No leading gap when the label is the first thing in the list. The sales-side checklist
   wraps rows in .checkout-questions, the estimate sheet in #checkout-questions. */
.checkout-questions > .checklist-group-label:first-child,
#checkout-questions > .checklist-group-label:first-child {
    margin-top: 0;
}

/* Checklist row: checkbox left, prompt right, inline on one line.
   Beats the global ".modal-content label { display:block }" rule. */
.modal-content label.checkout-check {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-weight: 600;
    cursor: pointer;
}

/* Reset the global ".modal-content input" min-width:96.5% so the checkbox stays small. */
.checkout-check input[type="checkbox"] {
    min-width: 0 !important;
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    margin: 0;
    cursor: pointer;
    accent-color: var(--accent-color-strong, var(--accent-color));
}

.checkout-question-label {
    flex: 1 1 auto;
    font-weight: 600;
}

.checkout-check .checkout-question-label {
    margin-bottom: 0;
    flex: 1 1 auto;
}

/* Icon button that reveals the optional note for a question (matches the other
   icon buttons). Shows a "+" by default and a trash icon once the note is open. */
.checkout-note-toggle {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    min-width: 28px !important;
    margin: 0;
    padding: 0 !important;
    border-radius: 8px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--sub-background-color);
    border: 1px solid var(--accent-color);
}

.checkout-note-toggle:hover {
    background: var(--secondary-accent-color);
}

.checkout-note-toggle-icon {
    content: url("/caddy/images/icons/add/light mode plus icon.png");
    width: 15px;
    height: 15px;
    display: block;
}

/* Once a note is open the button deletes it, so it shows the trash icon. */
.checkout-note-toggle.is-active .checkout-note-toggle-icon {
    content: url("/caddy/images/icons/trashcan/Light Trashcan.png");
}

/* Collapsible wrapper around the optional note. */
.checkout-note-wrap.hidden {
    display: none;
}

/* Optional per-question note, indented under the checkbox label. */
.checkout-note {
    width: 100%;
    box-sizing: border-box;
    resize: vertical;
    margin: 0.35rem 0 0 0;
    font-size: 0.85rem;
    min-height: 1.9rem;
}

.checkout-autosave-status {
    margin-left: 0.5rem;
    font-size: 0.8rem;
    font-weight: 400;
    opacity: 0.8;
}

.checkout-autosave-status.is-error {
    color: var(--error-color, #c0392b);
    opacity: 1;
}

textarea.checkout-answer,
.checkout-lesson-row textarea {
    width: 100%;
    box-sizing: border-box;
    resize: vertical;
}

/* Lesson card: trash button pinned top-right. */
.checkout-lesson-row {
    position: relative;
    border: 1px solid var(--sub-background-color);
    border-radius: 6px;
    padding: 0.6rem;
    padding-right: 2.5rem;
    margin-bottom: 0.6rem;
}

.checkout-lesson-fields {
    display: flex;
    gap: 0.5rem;
    align-items: flex-start;
    margin-bottom: 0.4rem;
    flex-wrap: wrap;
}

.checkout-lesson-fields .custom-dropdown {
    flex: 1 1 40%;
    min-width: 140px;
}

.checkout-lesson-target-wrap {
    flex: 1 1 40%;
    min-width: 140px;
}

/* Owner picker is only revealed when the row subject is "Owner"; */
/* syncTargetVisibility() toggles .hidden, but the checkout window loads no */
/* global .hidden rule, so hide it explicitly here. */
.checkout-lesson-target-wrap.hidden {
    display: none;
}

.checkout-lesson-target-wrap .custom-dropdown {
    width: 100%;
}

/* Trash icon button in the top-right corner of the card. */
.checkout-lesson-remove {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
    width: 28px;
    height: 28px;
    min-width: 28px !important;
    margin: 0 !important;
    padding: 0 !important;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--background-color);
    cursor: pointer;
}

.checkout-lesson-remove:hover {
    background: var(--secondary-accent-color);
}

.checkout-lesson-remove-icon {
    content: url("/caddy/images/icons/trashcan/Light Trashcan.png");
    width: 15px;
    height: 15px;
    display: block;
}

/* "Add lesson" reduced to a plus icon button. */
.checkout-add-lesson {
    width: 34px;
    height: 34px;
    min-width: 34px !important;
    margin-top: 0.35rem !important;
    padding: 0 !important;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--sub-background-color);
    cursor: pointer;
}

.checkout-add-lesson:hover {
    background: var(--secondary-accent-color);
    transform: scale(1.03);
}

.checkout-add-lesson-icon {
    content: url("/caddy/images/icons/add/light mode plus icon.png");
    width: 18px;
    height: 18px;
    display: block;
}

/* Submit stays disabled until every question is ticked. */
#checkout-submit:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* While the submit request is in flight. */
#checkout-submit.is-loading {
    cursor: progress;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

/* Inline spinner shown in the submit button while the checkout submits. */
.checkout-submit-spinner {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid color-mix(in srgb, currentColor 35%, transparent);
    border-top-color: currentColor;
    animation: cb-spin 0.8s linear infinite;
    flex: 0 0 auto;
}

/* Submit-mode estimate selector. */
.checkout-estimate-select {
    width: 100%;
    box-sizing: border-box;
}

/* The estimate selector becomes a custom dropdown; fill the content column. */
.modal-content.modal-two-tone .modal-form > .checkout-pane > .custom-dropdown {
    width: 100%;
    margin-top: 22px !important;
}

/* Estimate selector row: the dropdown grows, "Clear All" sits at the far right. */
.checkout-estimate-pane {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 22px;
}

.modal-content.modal-two-tone .modal-form > .checkout-estimate-pane > .custom-dropdown {
    width: auto;
    flex: 1 1 auto;
    min-width: 0;
    margin-top: 0 !important;
}

.checkout-estimate-pane > .checkout-clear-btn {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* Submit-mode recipient search box. */
.checkout-recipient-search {
    width: 100%;
    box-sizing: border-box;
    margin-bottom: 0.4rem;
}

/* Submit-mode email recipient picker. */
.checkout-recipients {
    max-height: 11rem;
    overflow-y: auto;
    border: 1px solid var(--sub-background-color);
    border-radius: 6px;
    padding: 0.4rem 0.6rem;
}

.checkout-recipient {
    display: flex !important;
    align-items: center;
    gap: 6px !important;
    cursor: pointer;
}

.checkout-recipient input[type="checkbox"] {
    min-width: 0;
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
    margin: 0;
    cursor: pointer;
}

.checkout-recipient-email {
    opacity: 0.7;
    font-size: 0.85rem;
}

/* Read-only checkout view (opened from the "Reviewed & cleared" badge), static
   lessons-learned rows, no inputs. */
.checkout-view-lessons {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.checkout-view-lesson {
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--sub-background-color);
    border-radius: 8px;
    background: color-mix(in srgb, var(--sub-background-color) 35%, transparent 65%);
}

.checkout-view-lesson-subject {
    font-weight: 700;
    margin-bottom: 0.25rem;
}

.checkout-view-lesson-text {
    white-space: pre-wrap;
    opacity: 0.9;
}

/* Modal header: title plus the "view past sheets" icon button, sitting inline. */
.checkout-header {
    display: flex;
    align-items: center;
    gap: 10px;
    background: color-mix(in srgb, var(--sub-background-color) 78%, var(--background-color) 22%);
}

/* "View past sheets" history button, an icon button next to the checkout title. */
.checkout-history-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    min-width: 0 !important;
    padding: 0;
    margin-top: 0 !important;
    border-radius: 8px;
    border: 1px solid var(--accent-color);
    color: var(--font-color);
    cursor: pointer;
}

.checkout-history-btn:hover {
    background: var(--secondary-accent-color);
}

.checkout-history-btn .icon-checkout {
    width: 20px;
    height: 22px;
    content: url("/caddy/images/icons/menu/light-checkout.png");
}

/* Checkout history popup (stacked over the in-progress sheet). */
.checkout-history-scope {
    margin: 0 0 12px 0;
    max-width: 220px;
}

.checkout-history-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-height: 50vh;
    overflow-y: auto;
}

.checkout-history-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    text-align: left;
    padding: 10px 12px !important;
    border: 1px solid var(--accent-color) !important;
    background: var(--sub-background-color) !important;
}

.checkout-history-item:hover {
    background: var(--secondary-accent-color) !important;
}

.checkout-history-item-main {
    font-weight: 600;
}

.checkout-history-item-date {
    opacity: 0.8;
    font-size: 0.82rem;
    white-space: nowrap;
}

/* Pagination controls under the history list (10 most recent per page). */
.checkout-history-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-top: 12px;
}

.checkout-history-pager:empty {
    margin-top: 0;
}

.checkout-history-page-btn {
    font-size: 0.82rem;
    padding: 5px 12px;
    border-radius: 8px;
    border: 1px solid var(--accent-color);
    background: var(--sub-background-color);
    color: var(--font-color);
    cursor: pointer;
}

.checkout-history-page-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.checkout-history-page-info {
    font-size: 0.82rem;
    opacity: 0.85;
}

/* Read-only "View Items" modal for an assembly (admin sidebar + estimate sidebar).
   Columns size to their content; headers never wrap, so each column is at least
   as wide as its header text. */
.modal-content.assembly-items-modal {
    width: fit-content;
    min-width: 360px;
    max-width: min(92%, 1000px);
}

.assembly-items-modal-scroll {
    width: fit-content;
    max-width: 100%;
    max-height: 60vh;
    overflow: auto;
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    background: var(--sub-background-color);
}

.assembly-items-modal-table {
    width: auto;
    min-width: 0;
    table-layout: auto;
    border-collapse: collapse;
    background: var(--sub-background-color);
}

.assembly-items-modal-table th,
.assembly-items-modal-table td {
    padding: 8px 12px;
    border-bottom: 1px solid var(--secondary-color);
    border-right: 1px solid var(--secondary-color);
    text-align: left;
    font-size: 13px;
    vertical-align: top;
}

.assembly-items-modal-table th {
    white-space: nowrap;
    font-weight: 600;
    background: var(--background-color);
    position: sticky;
    top: 0;
}

.assembly-items-modal-table tbody tr:last-child td {
    border-bottom: none;
}

.assembly-items-modal-empty {
    margin: 0.5rem 0 0;
    color: var(--font-color);
}

/* Add Hour Item modal */
.add-hour-item-modal {
    width: 640px;
    max-width: 92vw;
    min-height: 640px;
}

.add-hour-item-modal .ahi-field {
    margin-bottom: 12px;
}

.add-hour-item-modal .ahi-field label {
    display: block;
    font-weight: 600;
    font-size: 0.9rem;
}

/* Inline checkbox + label (reset the global full-width input rule) */
.add-hour-item-modal .ahi-checkbox-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 4px 0 14px;
    font-weight: 600;
    font-size: 0.9rem;
    cursor: pointer;
}

.add-hour-item-modal .ahi-checkbox-row input {
    min-width: 0;
    width: 16px;
    height: 16px;
    margin: 0;
    cursor: pointer;
}

.add-hour-item-modal .ahi-rates-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
}

.add-hour-item-modal .ahi-rates-note {
    margin-bottom: 10px;
    font-size: 0.82rem;
    opacity: 0.8;
    color: var(--font-color);
}

.add-hour-item-modal .ahi-rates-title {
    font-weight: 600;
    font-size: 0.9rem;
}

.hour-rate-rows {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.hour-rate-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 92px 92px 32px;
    gap: 25px;
    margin: 5px 0px;
    align-items: center;
}

/* Construction labor prices off Cost only: hide the Rate input and drop its column. */
.add-hour-item-modal.cost-only .hour-rate-row {
    grid-template-columns: minmax(0, 1fr) 92px 32px;
}

.add-hour-item-modal.cost-only .hour-rate-row [data-field="rate"] {
    display: none;
}

/* Reset the global .modal-content input/select sizing inside the grid */
.hour-rate-row input {
    min-width: 0;
    width: 100%;
    margin-top: 0;
}

.hour-rate-row select,
.hour-rate-row .custom-dropdown {
    width: 100%;
    margin-top: 0;
}

.hour-rate-remove-btn {
    width: 32px;
    height: 32px;
    min-width: 32px;
    padding: 0;
    border: 1px solid var(--accent-color);
    border-radius: 6px;
    background-color: var(--background-color);
    background-image: url("/caddy/images/icons/trashcan/Light Trashcan.png");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 16px 16px;
    cursor: pointer;
}

/* Per-row multi-select office dropdown (sits in the first column of .hour-rate-row) */
.add-hour-item-modal .ahi-office-dropdown {
    position: relative;
    width: 100%;
}

.add-hour-item-modal .ahi-office-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    padding: 6px 10px !important;
    margin-top: 0 !important;
    border: 1px solid var(--other-color) !important;
    border-radius: 6px !important;
    background-color: var(--background-color) !important;
    color: var(--font-color) !important;
    font-size: 0.9rem !important;
    cursor: pointer !important;
}

.add-hour-item-modal .ahi-office-summary {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.add-hour-item-modal .ahi-office-caret {
    flex: 0 0 auto;
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 6px solid var(--font-color);
}

.add-hour-item-modal .ahi-office-panel {
    position: absolute;
    z-index: 5;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    max-height: 240px;
    overflow-y: auto;
    padding: 6px;
    border: 1px solid var(--other-color);
    border-radius: 8px;
    background-color: var(--background-color);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.18);
}

.add-hour-item-modal .ahi-bulk-divider {
    height: 1px;
    margin: 4px 0;
    background-color: var(--other-color);
}

.add-hour-item-modal .ahi-bulk-option {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    margin: 0;
    padding: 8px 10px;
    border-radius: 6px;
    font-weight: 500;
    font-size: 0.9rem;
    cursor: pointer;
    transition: background-color 0.12s ease;
}

.add-hour-item-modal .ahi-bulk-option:hover {
    background-color: color-mix(in srgb, var(--font-color) 8%, transparent);
}

.add-hour-item-modal .ahi-bulk-option input[type="checkbox"] {
    flex: 0 0 auto;
    width: 16px;
    min-width: 16px;
    height: 16px;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    background-color: transparent !important;
    accent-color: var(--accent-color-strong, var(--accent-color));
    cursor: pointer;
}

.add-hour-item-modal .ahi-bulk-option span {
    flex: 1 1 auto;
    text-align: left;
}

/* An office already chosen in another row: greyed out and not selectable. */
.add-hour-item-modal .ahi-bulk-option.ahi-option-disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.add-hour-item-modal .ahi-bulk-option.ahi-option-disabled input[type="checkbox"] {
    cursor: not-allowed;
}

/* Updates modal: like/view buttons, tooltips, mention menu, resize handle.
   Copied here (from projects.css) so the shared updates modal is fully styled on
   pages that do not load projects.css, e.g. the /sales Actions page. */
.project-updates-resize-handle {
    position: absolute;
    top: 0;
    left: 0;
    width: 12px;
    height: 100%;
    cursor: ew-resize;
    z-index: 10;
}

/* The updates modal toggles elements (mention menu, error) with a .hidden class. The global
   .hidden rule lives in projects.css, so scope it here for pages that don't load it (/sales). */
#caddyModal.project-updates-shell .hidden {
    display: none !important;
}

/* Side-panel layout (copied from projects.css) so the updates modal slides in from the
   right on pages that do not load projects.css, e.g. the /sales grid. */
#caddyModal.project-updates-shell {
    position: fixed;
    inset: 0;
    display: block !important;
    background: transparent !important;
    pointer-events: none;
    z-index: 9000;
}

#caddyModal.project-updates-shell .project-updates-modal {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: auto;
    width: var(--project-updates-panel-width, 560px) !important;
    min-width: 420px;
    max-width: calc(100vw - 80px);
    height: 100vh;
    max-height: 100vh;
    margin: 0 !important;
    border-radius: 14px 0 0 14px;
    box-shadow: -8px 0 24px rgba(0, 0, 0, 0.28);
    pointer-events: auto;
    box-sizing: border-box;
    transform: none;
}

#caddyModal.project-updates-shell .project-updates-modal.modal-two-tone {
    overflow: hidden;
}

#caddyModal.project-updates-shell .project-updates-modal .modal-form {
    height: calc(100vh - 140px);
    max-height: calc(100vh - 140px);
    overflow: hidden;
    min-height: 0;
}

/* No tab bar (limited/estimator view): reclaim its height (~37px) so the content region
   fills the panel to the bottom instead of leaving a gap. */
#caddyModal.project-updates-shell .project-updates-modal.project-updates-no-tabs .modal-form {
    height: calc(100vh - 80px);
    max-height: calc(100vh - 80px);
}

#caddyModal.project-updates-shell .project-updates-list {
    padding-bottom: 24px;
    scroll-padding-bottom: 240px;
}

.project-update-mention-menu {
    position: fixed;
    z-index: 12000;
    max-height: 260px;
    overflow-y: auto;
}

/* The edit modal rides its own overlay at 12000, so its mention list has to clear that. Declared
   after the base rule above, which would otherwise win on source order at equal specificity. */
.project-update-edit-mention-menu {
    z-index: 12600;
}

.project-updates-resize-handle::before {
    content: "";
    position: absolute;
    top: 45%;
    left: 4px;
    width: 3px;
    height: 48px;
    border-radius: 999px;
    background: var(--accent-color);
    opacity: 0.8;
}

.project-updates-resize-handle:hover::before {
    opacity: 1;
}

body.is-resizing-project-updates {
    cursor: ew-resize;
    user-select: none;
}

.project-update-card-footer {
    display: flex;
    align-items: center;
    margin-top: 8px;
}

.project-update-like-wrap {
    position: relative;
    display: inline-flex;
}

.project-update-like-btn {
    position: relative;
    width: 28px;
    height: 28px;
    min-width: 28px !important;
    padding: 0 !important;
    margin-top: 0 !important;
    border: 1px solid var(--accent-color);
    border-radius: 999px;
    background-color: var(--background-color);
    background-image: url("/caddy/images/icons/updates/light-like.png");
    background-size: 15px 15px;
    background-repeat: no-repeat;
    background-position: center;
    color: var(--font-color);
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.project-update-like-btn:hover {
    background-color: var(--secondary-accent-color);
}

.project-update-like-btn.is-liked {
    background-color: var(--secondary-color) !important;
}

.project-update-like-btn.is-liked:hover {
    background-color: color-mix(in srgb, var(--primary-accent-color) 85%, black);
}

.project-update-like-btn:disabled {
    opacity: 0.65;
    cursor: default;
}

.project-update-like-btn span:first-child {
    display: none;
}

.project-update-like-count {
    display: inline-flex;
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: var(--secondary-color);
    color: #fff;
    font-size: 0.68rem;
    font-weight: 800;
    line-height: 1;
    box-sizing: border-box;
}

.project-update-like-tooltip {
    display: none;
    position: absolute;
    left: 0;
    right: auto;
    bottom: calc(100% + 3px);
    min-width: 150px;
    max-width: min(260px, calc(100vw - 24px));
    padding: 8px 10px;
    border-radius: 8px;
    background: rgba(20, 20, 20, 0.94);
    color: #fff;
    font-size: 0.78rem;
    line-height: 1.3;
    z-index: 3000;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
    box-sizing: border-box;
}

.project-update-like-wrap.has-likes:hover .project-update-like-tooltip {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.project-update-like-tooltip-title {
    font-weight: 800;
    opacity: 0.9;
    white-space: nowrap;
}

.project-update-like-tooltip-list {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.project-update-like-tooltip-person {
    white-space: nowrap;
}

.project-update-like-tooltip::before {
    content: "";
    position: absolute;
    left: 0;
    bottom: -8px;
    width: 100%;
    height: 8px;
}

.project-update-like-tooltip::after {
    content: "";
    position: absolute;
    left: 10px;
    right: auto;
    top: 100%;
    border: 6px solid transparent;
    border-top-color: rgba(20, 20, 20, 0.94);
}

.project-update-card-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
}

.project-update-view-wrap {
    position: relative;
    display: inline-flex;
    margin-left: auto;
}

.project-update-view-wrap.is-hidden {
    display: none;
}

.project-update-view-btn {
    position: relative;
    width: 28px;
    height: 28px;
    min-width: 28px !important;
    padding: 0 !important;
    margin-top: 0 !important;
    border: 1px solid var(--accent-color);
    border-radius: 999px;
    background-color: var(--background-color);
    background-image: url("/caddy/images/icons/updates/light-view.png");
    background-size: 15px 15px;
    background-repeat: no-repeat;
    background-position: center;
    color: var(--font-color);
}

.project-update-view-btn.is-viewed {
    border-color: var(--secondary-color);
    background-color: color-mix(in srgb, var(--secondary-color) 12%, var(--background-color));
}

.project-update-view-count {
    display: inline-flex;
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: var(--secondary-color);
    color: #fff;
    font-size: 0.68rem;
    font-weight: 800;
    line-height: 1;
    box-sizing: border-box;
}

.project-update-view-tooltip {
    display: none;
    position: absolute;
    right: 0;
    left: auto;
    bottom: calc(100% + 3px);
    min-width: 150px;
    max-width: min(260px, calc(100vw - 24px));
    padding: 8px 10px;
    border-radius: 8px;
    background: rgba(20, 20, 20, 0.94);
    color: #fff;
    font-size: 0.78rem;
    line-height: 1.3;
    z-index: 3000;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
    box-sizing: border-box;
}

.project-update-view-wrap.has-views:hover .project-update-view-tooltip {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.project-update-view-tooltip-title {
    font-weight: 800;
    opacity: 0.9;
    white-space: nowrap;
}

.project-update-view-tooltip-list {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.project-update-view-tooltip-person {
    white-space: nowrap;
}

.project-update-view-tooltip::before {
    content: "";
    position: absolute;
    left: 0;
    bottom: -8px;
    width: 100%;
    height: 8px;
}

.project-update-view-tooltip::after {
    content: "";
    position: absolute;
    right: 10px;
    left: auto;
    top: 100%;
    border: 6px solid transparent;
    border-top-color: rgba(20, 20, 20, 0.94);
}

/* Project/Sales-action updates chat button + unread badge. Copied from projects.css so the
   same icon/button renders on pages that do not load projects.css (e.g. the /sales grid).
   The projects-page sticky-column rules are intentionally NOT copied. */
.project-chat-cell {
    width: 42px;
    min-width: 42px;
    max-width: 42px;
    padding: 6px !important;
    overflow: visible !important;
    text-overflow: clip !important;
    white-space: nowrap;
    text-align: center;
}

.project-chat-button {
    position: relative;
    width: 28px;
    height: 28px;
    margin: 0 auto;
    padding: 4px;
    border: none;
    background: transparent;
    border-radius: 8px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.project-chat-button:hover {
    background: var(--secondary-accent-color);
}

.project-chat-icon {
    content: url("/caddy/images/icons/updates/light-chat.png");
    width: 18px;
    height: 18px;
    display: block;
}

.project-chat-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 15px;
    height: 15px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--secondary-accent-color);
    color: #fff;
    font-size: 10px;
    font-weight: 800;
    line-height: 15px;
    text-align: center;
    box-sizing: border-box;
}

#saf-note {
    display: flex;
    flex-direction: column;
}

/* Phone: modals fill the width and their label/field grids stack into one column. */
@media (max-width: 768px) {
    .modal {
        padding: 10px;
    }

    /* No modal should exceed the viewport on a phone. The high-specificity selector
       beats the per-modal width variants (chat, assembly-items, add-hour, etc.).
       Floating checkout window is excluded: JS sizes/positions it explicitly. */
    .modal:not(.modal-floating) .modal-content {
        width: 100%;
        max-width: 100%;
        min-width: 0;
    }

    .modal-content {
        padding: 16px;
    }

    /* The 96.5% min-width overflows once the 8px padding is added on a narrow screen. Checkboxes
       and radios are excluded, as above: stretching one to the full row is what left them as an
       invisible smear with the label pushed off screen. */
    .modal-content input:not([type="checkbox"]):not([type="radio"]),
    .modal-content input:not([type="checkbox"]):not([type="radio"]):focus,
    .modal-content input:not([type="checkbox"]):not([type="radio"]):active {
        min-width: 0;
        width: 100%;
        box-sizing: border-box;
    }

    /* Label/field grids stack: switching to block flow ignores every child's
       grid-column assignment, so nothing lands in a phantom second column. */
    .modal-content.modal-two-tone .modal-form,
    .modal-two-tone-question,
    .invite-details-modal .invite-details-form,
    .pc-contact-row {
        display: block;
        background: none;
        padding-right: 0;
    }

    /* Trim the desktop label padding now that labels sit above their fields. */
    .modal-content.modal-two-tone .modal-form > label,
    .pc-contact-row > label {
        padding: 10px 2px 2px;
        min-height: 0;
    }

    /* The two-tone question card loses its center divider once stacked. */
    .modal-two-tone-question-left {
        border-right: none;
    }

    /* Checkbox grid fills the row instead of two fixed 150px columns. */
    .download-options {
        grid-template-columns: 1fr 1fr;
    }

    /* Project Updates slide-in panel: full width instead of a 420-600px floor.
       Handled here (not projects.css) because modals.css loads last and wins. */
    .project-updates-modal,
    #caddyModal.project-updates-shell .project-updates-modal {
        width: calc(100vw - 20px) !important;
        min-width: 0;
        max-width: calc(100vw - 20px);
    }
}

/* Sales action scheduling: day-calendar timeline (shared schedule modal + New activity modal) */
.sched-timeline {
    position: relative;
    margin-top: 8px;
    max-height: 320px;
    overflow-y: auto;
    overflow-x: hidden;
    border: 1px solid var(--other-color);
    border-radius: 8px;
    background: var(--background-color);
}

.sched-tl-allday {
    position: sticky;
    top: 0;
    z-index: 4;
    padding: 6px 8px;
    font-size: 11px;
    color: var(--font-color);
    background: var(--sub-background-color);
    border-bottom: 1px solid var(--other-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sched-tl-body {
    position: relative;
    width: 100%;
}

.sched-tl-hour {
    position: absolute;
    left: 0;
    right: 0;
    height: 0;
    border-top: 1px solid var(--other-color);
}

.sched-tl-hour-label {
    position: absolute;
    top: 2px;
    left: 4px;
    padding: 0 3px;
    font-size: 10px;
    color: var(--secondary-color);
    background: var(--background-color);
}

.sched-tl-event {
    position: absolute;
    left: 50px;
    right: 8px;
    box-sizing: border-box;
    padding: 1px 6px;
    border-radius: 4px;
    background: rgba(96, 125, 174, 0.92);
    border: 1px solid rgba(70, 95, 140, 0.9);
    color: #ffffff;
    font-size: 11px;
    overflow: hidden;
}

.sched-tl-event-label {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Collaborator events overlay the user's own, striped + translucent so both read through */
.sched-tl-event-collab {
    background-color: rgba(214, 158, 46, 0.28);
    background-image: repeating-linear-gradient(45deg, rgba(214, 158, 46, 0.55) 0, rgba(214, 158, 46, 0.55) 5px, transparent 5px, transparent 10px);
    border: 1px solid rgba(214, 158, 46, 0.85);
    color: var(--font-color);
    z-index: 2;
}

.sched-tl-proposed {
    position: absolute;
    left: 50px;
    right: 8px;
    box-sizing: border-box;
    padding: 2px 6px;
    border-radius: 4px;
    background: rgba(52, 168, 102, 0.92);
    border: 1px solid #2f8f57;
    color: #ffffff;
    font-size: 11px;
    font-weight: 600;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
    z-index: 3;
}

/* The proposed slot is draggable to pick a start time (snaps to 30-min slots) */
.sched-tl-proposed.sched-tl-draggable {
    cursor: grab;
    touch-action: none;
}

.sched-tl-proposed.sched-tl-draggable:active {
    cursor: grabbing;
}

.sched-note {
    margin-top: 8px;
    font-size: 12px;
    color: var(--secondary-color);
}

.sched-collab-toggle {
    margin-top: 6px;
}

.sched-collab-toggle label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    cursor: pointer;
}

/* Reset the global .modal-content input min-width so this renders as a normal checkbox left of the label. */
.sched-collab-toggle input[type="checkbox"] {
    width: 16px;
    min-width: 16px;
    height: 16px;
    margin: 0;
    flex: 0 0 auto;
}

/* Approval decision modal uses the standard two-tone modal layout (220px label band + content
   column). Stack the label's text so "Notes are required." sits on its own line under "Notes"
   (the base two-tone label is a centered flex row, which would jam them together). */
.approval-decision-modal .modal-form > label {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 2px;
}

.approval-decision-modal #apd-note {
    min-height: 120px;
    resize: vertical;
}

/* Lightweight loading modal (showLoadingModal): centered spinner + message. */
.cb-loading-modal {
    max-width: 360px;
    text-align: center;
}

.cb-loading-body {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: 26px 24px;
}

.cb-loading-spinner {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 3px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    border-top-color: var(--primary-color);
    animation: cb-spin 0.8s linear infinite;
}

.cb-loading-text {
    margin: 0;
    color: var(--font-color);
    font-weight: 600;
}

@keyframes cb-spin {
    to { transform: rotate(360deg); }
}

/* Anchored confirm popover (openConfirmPopover). Sits above an open modal, for confirms that cannot
   use a modal because the page's only modal host is already occupied. */
.cb-confirm-popover {
    position: fixed;
    z-index: 12001;
    width: 260px;
    padding: 12px;
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    background: var(--modal-content-background-color);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.22);
    box-sizing: border-box;
}

.cb-confirm-popover-text {
    margin: 0 0 10px 0;
    color: var(--font-color);
    font-size: 0.9rem;
    line-height: 1.4;
    word-break: break-word;
}

.cb-confirm-popover-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

.cb-confirm-popover-cancel,
.cb-confirm-popover-confirm {
    padding: 6px 12px;
    border-radius: 8px;
    border: 1px solid var(--accent-color);
    background: var(--background-color);
    color: var(--font-color);
    cursor: pointer;
    font-size: 0.85rem;
}

.cb-confirm-popover-confirm {
    border-color: #b42318;
    background-color: rgba(180, 35, 24, 0.18);
}

/* Batch upload progress overlay (showUploadProgressModal). Owns its own overlay rather than
   #caddyModal so it can sit above an already open modal such as Add Files, hence the z-index
   above every other layer in this file. */
.cb-upload-progress-overlay {
    position: fixed;
    inset: 0;
    z-index: 12000;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 16px;
    background-color: rgba(0,0,0,0.5);
    box-sizing: border-box;
}

.cb-upload-progress-modal {
    background-color: var(--modal-content-background-color);
    color: var(--font-color);
    border: 2px solid var(--background-color);
    border-radius: 12px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.3);
    width: 380px;
    max-width: 100%;
    box-sizing: border-box;
}

.cb-upload-progress-body {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    padding: 26px 24px;
}

.cb-upload-progress-spinner {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 3px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    border-top-color: var(--primary-color);
    animation: cb-spin 0.8s linear infinite;
}

.cb-upload-progress-count {
    margin: 0;
    color: var(--font-color);
    font-weight: 600;
}

/* Long file names wrap instead of stretching the panel. */
.cb-upload-progress-file {
    margin: 0;
    width: 100%;
    text-align: center;
    color: var(--font-color);
    font-size: 13px;
    opacity: 0.75;
    word-break: break-all;
}

.cb-upload-progress-bar {
    width: 100%;
    height: 8px;
    border-radius: 999px;
    background-color: color-mix(in srgb, var(--primary-color) 18%, transparent);
    overflow: hidden;
}

.cb-upload-progress-fill {
    width: 0%;
    height: 100%;
    border-radius: 999px;
    background-color: var(--primary-color);
    transition: width 0.2s ease;
}

/* Estimate documents modals (upload + view). Styles live here so they work on the estimate,
   projects, and review pages, which all load modals.css but not admin.css. */

/* File and Folder tabs above the drop zone. One input cannot be both a file picker and a directory
   picker, so each tab owns its own hidden input. */
.estimate-docs-tabs {
    display: flex;
    gap: 6px;
    min-width: 0;
    margin-bottom: 10px;
}

.estimate-docs-tab {
    margin: 0;
    padding: 6px 14px;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--background-color);
    color: var(--font-color);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.estimate-docs-tab:hover {
    background: var(--sub-background-color);
}

.estimate-docs-tab.is-active {
    border-color: var(--primary-accent-color);
    background: color-mix(in srgb, var(--secondary-accent-color) 24%, var(--background-color));
}

/* Folder level delete on a tree row. Matches the per-file delete button. */
.file-tree-folder-delete {
    flex: 0 0 32px;
    width: 32px;
    min-width: 32px;
    height: 32px;
    margin: 0;
    padding: 0;
    border-radius: 8px;
    background-image: url("/caddy/images/icons/trashcan/Light Trashcan.png");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 18px 18px;
    background-color: var(--background-color);
    border: 1px solid var(--accent-color);
    cursor: pointer;
}

.estimate-docs-drop-zone {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 72px;
    padding: 14px;
    border: 2px dashed var(--accent-color);
    border-radius: 12px;
    background: var(--sub-background-color);
    cursor: pointer;
    min-width: 0;
}

.estimate-docs-drop-zone.is-drag-over {
    border-color: var(--primary-accent-color);
    background: color-mix(in srgb, var(--secondary-accent-color) 16%, transparent);
}

.estimate-docs-drop-zone.is-uploading {
    opacity: 0.7;
    pointer-events: none;
}

.estimate-docs-drop-main {
    opacity: 0.85;
    font-size: 0.95rem;
}

/* Allowed types and size cap, moved here from the old status strip. */
.estimate-docs-drop-hint {
    opacity: 0.6;
    font-size: 0.8rem;
}

.estimate-docs-browse-btn {
    background-color: var(--secondary-color);
}

.estimate-docs-status {
    min-height: 20px;
    display: flex;
    align-items: center;
    padding: 14px 0;
    font-size: 0.86rem;
    opacity: 0.78;
    min-width: 0;
}

/* Empty until an error or a skipped file list needs reporting. Beats display:flex from the base
   rule, which a shared .hidden utility would lose to. */
.estimate-docs-status.hidden {
    display: none;
}

.estimate-docs-status.is-error {
    color: #b42318;
    opacity: 1;
}

/* The status line centers a single message with flex, which fights a stacked list of skipped files.
   Applied only while the skipped file summary is showing. */
.estimate-docs-status.has-list {
    display: block;
    max-height: 160px;
    overflow-y: auto;
}

.estimate-docs-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: 360px;
    padding: 14px 0;
    padding-right: 4px;
    overflow-y: auto;
    min-width: 0;
}

.estimate-docs-empty {
    padding: 18px 16px;
    border: 1px dashed var(--accent-color);
    border-radius: 12px;
    background: var(--sub-background-color);
    text-align: center;
    opacity: 0.8;
}

.estimate-docs-empty.is-error {
    color: #b42318;
    opacity: 1;
}

.estimate-docs-card {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding: 10px 12px;
    border: 1px solid var(--accent-color);
    border-radius: 12px;
    background: var(--sub-background-color);
}

.estimate-docs-badge {
    width: 54px;
    height: 54px;
    flex: 0 0 54px;
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    background: var(--background-color);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.74rem;
    font-weight: 800;
    color: var(--font-color);
    text-decoration: none;
}

.estimate-docs-info {
    min-width: 0;
    flex: 1 1 auto;
}

.estimate-docs-name {
    display: block;
    min-width: 0;
    font-weight: 700;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--font-color);
}

.estimate-docs-meta {
    font-size: 0.82rem;
    opacity: 0.75;
}

/* Uploader and upload date, dimmer than the size line so it reads as secondary */
.estimate-docs-credit {
    font-size: 0.82rem;
    opacity: 0.6;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.estimate-docs-delete-btn {
    flex: 0 0 32px;
    width: 32px;
    min-width: 32px;
    height: 32px;
    padding: 0;
    border-radius: 8px;
    background-image: url("/caddy/images/icons/trashcan/Light Trashcan.png");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 18px 18px;
    background-color: var(--background-color);
    border: 1px solid var(--accent-color);
    cursor: pointer;
}

/* Invite add-files modal: shares more bid documents on an already-sent invite. Reuses the
   estimate-docs card family, so only the row buttons and the rename input are defined here. */

/* Wider than the default so file names and recipient meta fit on one line */
.modal-content.invite-add-files-modal {
    width: 1000px;
}

.invite-add-files-pick,
.invite-add-files-remove {
    flex: 0 0 auto;
    min-width: 74px;
    height: 32px;
    margin: 0;
    padding: 0 10px;
    border-radius: 8px;
    border: 1px solid var(--accent-color);
    background-color: var(--background-color);
    color: var(--font-color);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.invite-add-files-pick:hover,
.invite-add-files-remove:hover {
    border-color: var(--primary-color);
    background-color: var(--secondary-color);
}

/* width/min-width reset undoes the global ".modal-content input" min-width:96.5% */
.invite-add-files-name-input {
    display: block;
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
    margin-bottom: 4px;
    padding: 4px 8px;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--background-color);
    color: var(--font-color);
    font: inherit;
    font-weight: 700;
}

/* Keep the existing and staged lists from growing past the modal on long projects */
.invite-add-files-existing,
.invite-add-files-staged,
.invite-add-files-recipients {
    max-height: 440px;
    overflow-y: auto;
}

/* Approval status timeline (Status tab of the read-only sales checklist modal). */
.approval-timeline {
    display: flex;
    flex-direction: column;
    padding: 6px 4px;
}

/* A merged change order's approval trail, shown under the parent's on the same Status tab. The
   rule above it separates the two trails so they don't read as one sequence. */
.approval-timeline-section {
    margin-top: 6px;
    padding-top: 14px;
    border-top: 1px solid color-mix(in srgb, var(--other-color) 55%, transparent);
}

.approval-timeline-section-title {
    padding: 0 4px 2px;
    color: var(--header-color);
    font-size: 0.9rem;
    font-weight: 700;
}

.approval-timeline-step {
    position: relative;
    display: flex;
    gap: 12px;
    padding: 0 0 18px 0;
}

/* Each step exposes its state color via --tl-color; the dot and the connector below it both use it
   so the line itself is colored, not just the dots. Default is the neutral accent (pending). */
.approval-timeline-step {
    --tl-color: var(--accent-color);
}

/* The connector line runs from each dot down to the next step, colored by this step's state. */
.approval-timeline-step::before {
    content: "";
    position: absolute;
    left: 8px;
    top: 22px;
    bottom: 0;
    width: 2px;
    background: var(--tl-color);
}

.approval-timeline-step:last-child::before {
    display: none;
}

.approval-timeline-dot {
    flex: 0 0 auto;
    width: 14px;
    height: 14px;
    margin-top: 2px;
    border-radius: 999px;
    background: var(--tl-color);
    border: 2px solid var(--tl-color);
}

.approval-timeline-content {
    flex: 1 1 auto;
    min-width: 0;
}

.approval-timeline-title {
    font-weight: 600;
    color: var(--font-color);
}

.approval-timeline-state {
    margin-left: 6px;
    font-size: 0.78rem;
    font-weight: 600;
}

.approval-timeline-meta {
    margin-top: 2px;
    font-size: 0.82rem;
    color: var(--secondary-color);
}

.approval-timeline-notes {
    margin-top: 4px;
    padding: 6px 8px;
    border-radius: 6px;
    font-size: 0.85rem;
    color: var(--font-color);
    background: var(--sub-background-color);
    white-space: pre-wrap;
    word-break: break-word;
}

/* Per-state colors. Each state sets --tl-color (drives both the dot and the connector line below it)
   and a matching state-label color, mixed with --font-color so both themes read correctly. */
.approval-timeline-step.is-done {
    --tl-color: #2e9e5b;
}

.approval-timeline-step.is-done .approval-timeline-state {
    color: color-mix(in srgb, #2e9e5b 80%, var(--font-color) 20%);
}

.approval-timeline-step.is-notready {
    --tl-color: #e0821e;
}

.approval-timeline-step.is-notready .approval-timeline-state {
    color: color-mix(in srgb, #b5641a 82%, var(--font-color) 18%);
}

.approval-timeline-step.is-seerevisions {
    --tl-color: #e0730a;
}

.approval-timeline-step.is-seerevisions .approval-timeline-state {
    color: color-mix(in srgb, #b5540a 82%, var(--font-color) 18%);
}

.approval-timeline-step.is-denied {
    --tl-color: #d64545;
}

.approval-timeline-step.is-denied .approval-timeline-state {
    color: color-mix(in srgb, #d64545 82%, var(--font-color) 18%);
}

/* Pending: muted gray dot + line so waiting steps read as not-yet-reached. */
.approval-timeline-step.is-pending {
    --tl-color: color-mix(in srgb, var(--secondary-color) 70%, transparent);
}

.approval-timeline-step.is-pending .approval-timeline-dot {
    background: var(--background-color);
}

.approval-timeline-step.is-pending .approval-timeline-state {
    color: color-mix(in srgb, #a68a00 82%, var(--font-color) 18%);
}

/* "Files updated" event (salesperson revised docs after See Revisions): distinct blue. */
.approval-timeline-step.is-updated {
    --tl-color: #3a7bd5;
}

.approval-timeline-step.is-updated .approval-timeline-state {
    color: color-mix(in srgb, #3a7bd5 82%, var(--font-color) 18%);
}

/* The Legal "I've updated the files" action shown on a See Revisions step. */
.approval-timeline-actions {
    margin-top: 8px;
}

.approval-timeline-update-btn {
    padding: 6px 12px;
    font-size: 0.85rem;
}

/* Project Logs modal (openProjectLogsModal): global feed of project field changes. */
/* Body sits below the two-tone header band and carries its own tinted background + padding
   so the header and body read as two distinct panels. */
.modal-content.modal-two-tone .pl-body {
    padding: 18px 22px 22px;
    background: color-mix(in srgb, var(--background-color) 88%, black 12%);
}

.pl-toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 12px;
}

.modal-content .pl-search {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    margin-top: 0;
    box-sizing: border-box;
}

/* Filter icon button, styled to match the projects page #filter-projects button. */
.modal-content .pl-filter-toggle {
    flex: 0 0 auto;
    margin-top: 0;
    padding: 8px;
    background-color: var(--sub-background-color);
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s ease;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: relative;
}

.modal-content .pl-filter-toggle:hover {
    background-color: var(--secondary-accent-color);
    transform: scale(1.03);
}

.pl-filter-toggle img {
    width: 20px;
    height: 20px;
    display: block;
}

/* Active-filter indicator dot, matching #filter-projects.has-filters. */
.pl-filter-toggle.has-filters::after {
    content: "";
    position: absolute;
    width: 8px;
    height: 8px;
    border-radius: 999px;
    top: 4px;
    right: 4px;
    background: var(--secondary-color);
}

/* Override the generic modal-button top margin so footer/action buttons align cleanly.
   Uses IDs so the specificity beats the :not()-heavy generic .modal-content button rule. */
.modal-content #pl-prev,
.modal-content #pl-next,
.modal-content #pl-filter-clear,
.modal-content #pl-filter-apply,
.modal-content #comm-logs-prev,
.modal-content #comm-logs-next {
    margin-top: 0 !important;
}

.pl-filters {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 10px 14px;
    align-items: end;
    padding: 14px;
    margin-bottom: 12px;
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    background: var(--sub-background-color);
}

/* Dropdown triggers inside the filter panel: distinct (darker) background so they stand out
   against the lighter panel. */
.pl-filters .custom-dropdown-trigger {
    background: color-mix(in srgb, var(--background-color) 85%, black 15%);
    border: 1px solid var(--accent-color);
}

.pl-filters.hidden {
    display: none;
}

/* Neither stylesheet this modal loads defines a generic .hidden, so the pager needs its own rule.
   Hidden whenever there is only one page (see openCommissionLogsModal). */
.pl-footer.hidden {
    display: none;
}

.pl-filter-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.pl-filter-field > label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--font-color);
    opacity: 0.85;
}

.pl-filter-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    grid-column: 1 / -1;
}

.pl-list {
    max-height: 55vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-right: 4px;
}

.pl-empty {
    padding: 24px 8px;
    text-align: center;
    color: var(--muted-font-color, var(--font-color));
    opacity: 0.7;
}

.pl-row {
    border: 1px solid var(--accent-color);
    border-radius: 10px;
    padding: 10px 12px;
    background: var(--sub-background-color);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
}

/* The job name heads the row on the board feed. Its own line, so a long customer name cannot
   squeeze the sentence beside it down to a few words. */
/* Contact detail popup, opened from a quote's contact badge. The rows are label and value pairs
   straight into the two tone grid, so the label column and its tint come from .modal-form rather
   than from an inner grid of their own. */
.svc-contact-value {
    display: flex;
    align-items: center;
    min-height: 52px;
    padding: 14px 18px;
    word-break: break-word;
}

/* The no details case has nothing to label, so it stays in the right column and just needs the
   same padding the value rows carry */
.svc-contact-empty-note {
    padding: 14px 18px;
    opacity: 0.75;
    font-style: italic;
}

.pl-row-head {
    margin-bottom: 4px;
}

.pl-row-top {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    margin-bottom: 6px;
}

/* What happened, which is the line the eye should land on first */
.pl-sentence {
    font-weight: 600;
    color: var(--font-color);
}

/* The meta line is supporting detail, so it sits behind a divider rather than beside the change */
.pl-row-meta {
    border-top: 1px solid color-mix(in srgb, var(--accent-color) 60%, transparent);
    padding-top: 6px;
}

.pl-project {
    font-weight: 700;
    color: var(--font-color);
}

.pl-field {
    font-size: 0.8rem;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--background-color);
    border: 1px solid var(--accent-color);
    color: var(--font-color);
    white-space: nowrap;
}

.pl-change {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin: 4px 0;
}

.pl-change-create {
    font-style: italic;
    opacity: 0.85;
}

.pl-change-sentence {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

/* Delete rows state what happened, matching the italic treatment of the created row */
.pl-change-delete .pl-sentence {
    font-style: italic;
    opacity: 0.85;
}

.pl-sentence {
    font-weight: 500;
    color: var(--font-color);
}

/* Reason text sits on its own line and wraps, since the point is to read it without hovering */
.pl-event-detail {
    flex-basis: 100%;
    font-size: 0.85rem;
    color: var(--muted-font-color, var(--font-color));
    opacity: 0.8;
    white-space: normal;
}

.pl-value {
    padding: 2px 8px;
    border-radius: 6px;
    background: var(--background-color);
    border: 1px solid var(--accent-color);
    font-size: 0.85rem;
    color: var(--font-color);
}

.pl-value-status {
    border-color: transparent;
    font-weight: 600;
}

/* Placeholder pill for a blank old/new value ("None") */
.pl-value-empty {
    background: transparent;
    border-style: dashed;
    color: var(--muted-font-color, var(--font-color));
    font-style: italic;
    opacity: 0.7;
}

/* Long text values (notes) truncate instead of wrapping the whole row */
.pl-value-text {
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pl-arrow {
    opacity: 0.6;
    flex-shrink: 0;
}

/* Jump button sits just left of the timestamp */
.pl-row-meta-right {
    display: flex;
    align-items: flex-end;
    gap: 6px;
    flex-shrink: 0;
}

/* Open icon; swapped for the dark variant in palette.css. Scoped to .modal-content and
   resetting margin/min-width so the generic ".modal-content button" rule can't reshape it. */
.modal-content .pl-goto {
    flex: 0 0 auto;
    margin-top: 0;
    min-width: 0;
    width: 22px;
    height: 22px;
    padding: 0;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    background-color: transparent;
    background-image: url("/caddy/images/icons/share/share-light.png");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 14px 14px;
    opacity: 0.75;
    transition: background-color 0.15s ease, opacity 0.15s ease;
}

.modal-content .pl-goto:hover {
    background-color: color-mix(in srgb, var(--other-color) 40%, transparent);
    opacity: 1;
}

/* Fade the text only, so the jump icon keeps its own opacity */
.pl-row-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 6px;
    font-size: 0.78rem;
}

.pl-user,
.pl-time {
    opacity: 0.75;
}

.pl-footer {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin-top: 12px;
}

.pl-page-info {
    font-size: 0.85rem;
    opacity: 0.8;
}
/*** Delete-project confirm modal (typed confirmation) ***/

.modal-content .dp-gate-prompt {
    margin-top: 12px;
    margin-bottom: 6px;
    font-size: 0.9rem;
}

.modal-content .dp-phrase {
    padding: 1px 6px;
    border-radius: 4px;
    background-color: var(--accent-color);
    font-family: monospace;
    font-weight: 700;
    letter-spacing: 0.03em;
    /* Not selectable, so the phrase can't be dragged or copied straight into the field. */
    user-select: none;
}

.modal-content .dp-confirm-input {
    width: 100%;
    box-sizing: border-box;
}

.modal-content .dp-gate-error {
    margin-top: 6px;
    margin-bottom: 0;
    font-size: 0.82rem;
    font-weight: 600;
    color: #d9534f;
}

/* Disabled until the typed phrase matches, so the armed state needs to read as the live one. */
.modal-content #dp-delete:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.modal-content #dp-delete.dp-delete-armed {
    background-color: #d9534f;
    border-color: #d9534f;
    color: #ffffff;
}

/* BuildOps job setup modal: a single-field prompt, so tighten the two-tone row
   padding that is sized for taller multi-field forms. A cell holding a field plus its note is
   taller than the input, so top-align the label to keep it beside the input, not the pair. */
.buildops-job-setup-modal.modal-two-tone .modal-form > label {
    min-height: 32px;
    padding: 0px 18px;
    align-items: center;
}

.buildops-job-setup-modal.modal-two-tone .modal-form > input,
.buildops-job-setup-modal.modal-two-tone .modal-form > .buildops-field > input {
    padding: 5px 8px;
    min-height: 32px;
}

/* Explains a prefilled job number on a change order. Sits under the input, in the value column. */
.buildops-job-setup-modal .buildops-job-number-note {
    font-size: 0.82rem;
    line-height: 1.35;
    color: color-mix(in srgb, var(--font-color) 62%, transparent);
}

/* Field + its note share one column-2 cell, so the note never owns a grid row of its own. The
   two-tone form places children by column only, so a bare note would sit in a row whose column 1
   can never be filled (auto-placement does not backtrack) and the next label would start a fresh
   row, leaving the note's height as a blank band beside it. */
.buildops-job-setup-modal.modal-two-tone .modal-form > .buildops-field {
    grid-column: 2;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

/* Lines the note's text up with the value it explains, matching the input's own left padding. */
.buildops-job-setup-modal.modal-two-tone .modal-form > .buildops-field > .buildops-job-number-note {
    padding-left: 8px;
}

/* Create-project step 1: pick the project type before the form opens, so the type is always a
   deliberate choice instead of whatever the dropdown defaulted to. Keeps the two-tone grid, so
   the "Type" label sits in the left column exactly like every other field. */
.modal-content .cp-type-choices {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    min-width: 0;
}

/* Selectable cards rather than plain buttons: a radio dot on the left makes it obvious these
   are one-of-N choices, and the picked one stays filled. Overrides the generic
   ".modal-content button" sizing (min-width / margin-top / centered text). */
.modal-content .cp-type-choice {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-width: 0;
    /* !important on the properties the generic ".modal-content button" rule also sets: it has
       far higher specificity (15 :not()s) and would otherwise restore the pill look. */
    margin-top: 0 !important;
    padding: 14px 16px !important;
    text-align: left;
    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--font-color);
    background-color: color-mix(in srgb, var(--sub-background-color) 55%, transparent) !important;
    border: 1px solid color-mix(in srgb, var(--font-color) 22%, transparent) !important;
    border-radius: 8px !important;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

/* The radio dot. ::before is the ring, the inset box-shadow fills it once selected. */
.modal-content .cp-type-choice::before {
    content: "";
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    border: 2px solid color-mix(in srgb, var(--font-color) 45%, transparent);
    border-radius: 50%;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* !important throughout: the generic ".modal-content ... button:hover" rule above carries far
   higher specificity (many :not()s) and would otherwise repaint both the hover and the selected
   card with the plain button colors. */
.modal-content .cp-type-choice:hover {
    background-color: color-mix(in srgb, var(--sub-background-color) 80%, transparent) !important;
    border-color: color-mix(in srgb, var(--primary-color) 60%, transparent) !important;
}

.modal-content .cp-type-choice.is-selected,
.modal-content .cp-type-choice.is-selected:hover {
    background-color: color-mix(in srgb, var(--primary-color) 30%, transparent) !important;
    border-color: var(--primary-color) !important;
    box-shadow: inset 3px 0 0 0 var(--primary-color);
}

.modal-content .cp-type-choice.is-selected::before,
.modal-content .cp-type-choice.is-selected:hover::before {
    border-color: var(--primary-color);
    box-shadow: inset 0 0 0 4px var(--primary-color);
}

/* Project type change: pick the parent job and the CO number when a won project becomes a change
   order. Same field + note pairing as the BuildOps job setup modal, so the notes never own a grid
   row of their own in the two-tone form. */
.project-type-change-modal.modal-two-tone .modal-form > .ptc-field {
    grid-column: 2;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.project-type-change-modal.modal-two-tone .modal-form > input,
.project-type-change-modal.modal-two-tone .modal-form > .ptc-field > input {
    padding: 5px 8px;
    min-height: 32px;
}

.project-type-change-modal .ptc-note {
    font-size: 0.82rem;
    line-height: 1.35;
    color: color-mix(in srgb, var(--font-color) 62%, transparent);
    padding-left: 8px;
}

/* Number box and its button on one line, the box taking whatever space is left. */
.project-type-change-modal .ptc-search-row {
    display: flex;
    gap: 8px;
    align-items: center;
    min-width: 0;
}

.project-type-change-modal .ptc-search-row > input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 5px 8px;
    min-height: 32px;
}

.project-type-change-modal .ptc-search-row > button {
    flex: 0 0 auto;
    min-height: 32px;
}

/* Only shown when a search returns more than one job, so the right one can be picked. */
.project-type-change-modal .ptc-search-results {
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-height: 180px;
    overflow-y: auto;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    padding: 4px;
    background: var(--background-color);
}

.project-type-change-modal .ptc-search-results.hidden {
    display: none;
}

.project-type-change-modal .ptc-search-hit {
    text-align: left;
    padding: 6px 8px;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--font-color);
    cursor: pointer;
}

.project-type-change-modal .ptc-search-hit:hover {
    background: color-mix(in srgb, var(--accent-color) 22%, transparent);
}

/* States what the switch does before it is made: the row leaves the grid and the value moves. */
.project-type-change-modal .ptc-warn {
    grid-column: 1 / -1;
    font-size: 0.86rem;
    line-height: 1.45;
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid color-mix(in srgb, var(--accent-color) 55%, transparent);
    background: color-mix(in srgb, var(--accent-color) 12%, transparent);
}

/* A message in the results box (searching, nothing found, failed), not a pickable row. Muted and
   unhoverable so it never reads as a result that can be clicked. */
.project-type-change-modal .ptc-search-note {
    padding: 8px;
    font-size: 0.88rem;
    line-height: 1.4;
    color: color-mix(in srgb, var(--font-color) 68%, transparent);
}

/* The CADdy Bid change order behind a commission line: its name, number and estimate values.

   buildProjectInfoRow emits .project-info-readonly-value, which is styled in projects.css and
   admin.css. The commissions page loads neither, so the rule is repeated here scoped to this modal
   rather than leaving the values unstyled. */
.comm-bid-co-modal .project-info-readonly-value {
    min-height: 40px;
    display: flex;
    align-items: center;
    padding: 8px 10px;
    background: var(--sub-background-color);
    overflow-wrap: anywhere;
}

/* Loading, failed and no-estimate all share this line: each is one short sentence where the content
   would otherwise be, and none of them is an error the reader has to act on. */
.comm-bid-co-modal .comm-bid-co-loading {
    padding: 8px 0;
    color: color-mix(in srgb, var(--font-color) 68%, transparent);
}

.comm-bid-co-modal .comm-bid-co-est-head {
    margin-top: 14px;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: color-mix(in srgb, var(--font-color) 62%, transparent);
}

/* One estimate, its rows grouped under its own name so several read as a list rather than as one
   long run of label and value pairs. */
.comm-bid-co-modal .comm-bid-co-est {
    margin-top: 8px;
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid var(--accent-color);
}

.comm-bid-co-modal .comm-bid-co-est-name {
    font-weight: 600;
    margin-bottom: 6px;
}


/*  Service quote next step: send for approval, and the Changes Saved handoff  */

/* The value cells sit in the two-tone grid's right column, so they take the same vertical rhythm
   as the labels opposite them. */
.service-approval-submit-modal .modal-form > .sasm-value,
.service-next-step-modal .modal-form > .sasm-value {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 14px 18px 14px 0;
    font-size: 0.95rem;
}

/* The figure that decides whether this needs approval at all, so it carries the emphasis */
.service-approval-submit-modal .sasm-total,
.service-next-step-modal .sasm-total {
    font-size: 1.05rem;
    font-weight: 700;
}

/* The recipients read as a named list rather than a run of emails, so it is obvious who gets the
   approval email before it sends. */
.service-approval-submit-modal .sasm-recipients,
.service-next-step-modal .sasm-recipients {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.service-approval-submit-modal .sasm-recipients li,
.service-next-step-modal .sasm-recipients li {
    display: flex;
    flex-direction: column;
    overflow-wrap: anywhere;
}

.service-approval-submit-modal .sasm-recipient-name,
.service-next-step-modal .sasm-recipient-name {
    font-weight: 600;
}

.service-approval-submit-modal .sasm-recipient-email,
.service-next-step-modal .sasm-recipient-email {
    color: color-mix(in srgb, var(--font-color) 65%, transparent);
    font-size: 0.86rem;
}

.service-approval-submit-modal .sasm-recipients-empty,
.service-next-step-modal .sasm-recipients-empty {
    color: color-mix(in srgb, var(--font-color) 65%, transparent);
    font-size: 0.9rem;
    line-height: 1.45;
}

/* Both labels are long, so a shared min-width keeps the two buttons the same size */
.service-approval-submit-modal .project-button-row button {
    min-width: 170px;
}

/* Up to four buttons here, so they wrap rather than squeeze, and a smaller shared min-width keeps
   them even without forcing the row wider than the modal. Both row classes, since this modal uses
   the question layout when it has no detail rows to show. */
.service-next-step-modal .project-button-row,
.service-next-step-modal .button-row {
    flex-wrap: wrap;
    row-gap: 10px;
}

.service-next-step-modal .project-button-row button,
.service-next-step-modal .button-row button {
    min-width: 150px;
}

/*  Email for Signature modal  */

/* Wider than a normal two-tone modal because it carries a live email preview beside its controls,
   and the preview is only useful at a readable width. */
.service-email-signature-modal {
    width: min(1100px, 96vw);
    max-width: min(1100px, 96vw);
}

.service-email-signature-modal .sesm-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.service-email-signature-modal .sesm-hint {
    margin: 0;
    color: var(--other-color);
    font-size: 0.82rem;
    line-height: 1.4;
}

/* Reserved with a non breaking space in the markup, so the layout does not jump as the preview
   goes from idle to updating and back. */
.service-email-signature-modal .sesm-preview-state {
    min-height: 1.2em;
}

/* background-color, not input-color: despite the name, --input-color is the purple focus outline
   hue, so using it as a fill turns the box lavender. Matches .modal-form textarea. */
.service-email-signature-modal .sesm-textarea {
    width: 100%;
    padding: 7px 10px;
    border: 1px solid var(--other-color);
    border-radius: 6px;
    background: var(--background-color);
    color: var(--font-color);
    font-family: inherit;
    font-size: 0.9rem;
    resize: vertical;
    box-sizing: border-box;
}

/* White, whatever the app theme: the iframe renders a real email, and the email's own light
   palette should not sit on a dark modal background as if it were part of the app. */
.service-email-signature-modal .sesm-preview {
    width: 100%;
    height: 420px;
    border: 1px solid var(--other-color);
    border-radius: 8px;
    background: #ffffff;
}

.service-email-signature-modal .sesm-error {
    margin: 0;
    color: #c0392b;
    font-size: 0.85rem;
    font-weight: 600;
}

/* The search box fills the row beside the filter button. flex-grow rather than a width, and the
   global modal input min-width of 96.5% is reset, which would otherwise push the button onto its
   own line instead of letting the input shrink to share the row. */
.service-email-signature-modal .saa-toolbar #sesm-search {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    margin-top: 0;
}

/* The recipient list carries its own border, so it does not need the field wrapper spacing */
.service-email-signature-modal .saa-list {
    min-height: 220px;
    max-height: 300px;
}

/* Who is selected, in its own block above the scroller. It does not scroll and has no minimum, so
   it takes only the room its rows need and stays on screen while the list below is scrolled. The
   cap is a safety valve for a very long recipient list, which scrolls here rather than pushing the
   list and the send button off the modal. */
.service-email-signature-modal .sesm-picked {
    min-height: 0;
    max-height: 210px;
    margin-bottom: 6px;
    border-color: var(--primary-color);
}

/* The scroller is the one that needs the room, so it keeps its floor even with picks shown */
.service-email-signature-modal .sesm-picked + .saa-list {
    min-height: 180px;
}

/* A contact with no address on file is still listed, and reads as an invitation to add one */
.service-email-signature-modal .sesm-no-email {
    color: var(--secondary-color);
    font-style: italic;
}

/* The preview is the first thing to give up its height on a short or narrow screen, since the
   controls are what the user is actually filling in. */
@media (max-width: 900px) {
    .service-email-signature-modal .sesm-preview {
        height: 260px;
    }
}

/*  Change Contact modal: city/zip location cascade  */

/* The label reads to the left of its dropdown here, not stacked above it */
#ct-location .admin-sub-location-row label {
    flex-direction: row;
    align-items: center;
    gap: 8px;
}

/* City and Zip share the row evenly, so neither dropdown is squeezed */
#ct-location .admin-sub-location-row label.admin-sub-loc-city,
#ct-location .admin-sub-location-row label.admin-sub-loc-zip,
#ct-location .admin-sub-location-row label.admin-sub-loc-newcity,
#ct-location .admin-sub-location-row label.admin-sub-loc-newzip {
    flex: 1 1 200px;
    width: auto;
}

/* The shared 50px cap is for the multi-row admin lists, too narrow for a single row here */
#ct-location .admin-sub-location-row input,
#ct-location .admin-sub-location-row select {
    max-width: none;
    width: 100%;
}

/* The generated dropdown wrapper carries the width, so it has to flex too */
#ct-location .admin-sub-location-row label .custom-dropdown {
    flex: 1 1 auto;
    min-width: 0;
}

/* Ready for Approval requirements modal. Laid out as ordinary two-tone grid children: the
   label sits in the shaded left column and its controls in the right, the same way the
   People modal does it. */
.par-sub-title {
    display: block;
    margin-top: 5px;
    font-size: 13px;
    font-weight: 600;
    color: var(--font-color);
    opacity: 0.75;
}

/* The control side of one band. Its label is a separate grid child in column 1. */
.modal-content.modal-two-tone .par-form > .par-control {
    grid-column: 2;
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 0;
    padding: 12px 18px;
    min-width: 0;
    box-sizing: border-box;
}

.par-note {
    font-size: 0.8rem;
    color: var(--font-color);
    opacity: 0.75;
}

/* A sub-field inside a control: its own small label above the input, since the band's real
   label already lives in the left column. */
/* These carry .hidden until a pick reveals them, and .hidden is the same specificity while
   modals.css loads later, so a plain display:flex here would win and every sub-field would
   render. Scoped under .par-control to outrank it, with an explicit hidden guard. */
.par-control .par-subs {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.par-control .par-sub {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.par-control .par-subs.hidden,
.par-control .par-sub.hidden {
    display: none !important;
}

.par-sub-label {
    font-size: 0.78rem;
    font-weight: 600;
    opacity: 0.8;
}

.par-check-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* Checkbox left, label right. The input reset matters: without it the checkbox inherits
   the global .modal-content input box styling and renders as a large empty text box. */
.modal-content .par-check,
.modal-content .par-confirm {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 0;
    font-size: 0.85rem;
    cursor: pointer;
}

/* Radios as well as checkboxes: the winning bidder is single select, and a rule that
   named only checkboxes left the radios to the global ".modal-content input" width,
   which stretches them to 96.5% and shoves the label off the right edge.
   min-width needs !important for the same reason .checkout-check does. */
.modal-content .par-check input[type="checkbox"],
.modal-content .par-check input[type="radio"],
.modal-content .par-confirm input[type="checkbox"],
.modal-content .par-confirm input[type="radio"] {
    flex: 0 0 auto;
    width: 16px;
    min-width: 16px !important;
    max-width: 16px;
    height: 16px;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    background-color: transparent !important;
    accent-color: var(--accent-color-strong, var(--accent-color));
    cursor: pointer;
}

/* The label text takes the rest of the row and wraps rather than being clipped. */
.modal-content .par-check span,
.modal-content .par-confirm span {
    flex: 1 1 auto;
    min-width: 0;
    text-align: left;
}

.modal-content .par-confirm {
    margin-top: 4px;
    font-weight: 600;
}

/* Guidance line with its add button on the right, used by the repeatable bands (sales
   split, links) so both read the same way. */
.par-note-row {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.par-note-row .par-note {
    flex: 1 1 auto;
    min-width: 0;
}

.par-note-row .pc-add-contact-btn {
    flex: 0 0 auto;
}

/* A header bar with no title is just the add button, so it takes no vertical space of
   its own; the band's note row carries the button instead. */
.pc-role-section-header-bare {
    display: none;
}

/*  Add a person, from the signature recipient picker  */

/* Same 40px box as the filter button beside it, so the toolbar reads as one row of controls */
/* Built exactly like .saa-filter-btn beside it, down to the 18px background image: a text glyph
   rendered smaller than the filter icon and sat on a different baseline. */
.saa-add-btn {
    flex: 0 0 auto;
    /* Not inline-block: the global .modal-content button rule gives this font: inherit, and an
       inline-block button aligns on its text baseline, which sat the icon a couple of pixels below
       the filter button next to it. A block level box has no baseline to sit on. */
    display: block;
    line-height: 0;
    width: 40px;
    min-width: 40px !important;
    height: 40px;
    padding: 0;
    border: 1px solid var(--primary-accent-color);
    border-radius: 10px;
    background-color: color-mix(in srgb, var(--secondary-accent-color) 18%, var(--background-color));
    background-image: url("/caddy/images/icons/add/light mode plus icon.png");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 18px 18px;
    /* The global .modal-content button rule adds margin-top: 15px, which pushed this out of line
       with the search box and the filter button beside it. */
    margin-top: 0;
    cursor: pointer;
}

.saa-add-btn:hover {
    border-color: var(--primary-color) !important;
    background-color: var(--secondary-accent-color) !important;
}

.modal-content.scp-modal {
    width: min(620px, 94vw);
}

.scp-modal .scp-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.scp-modal .scp-hint {
    margin: 0;
    color: var(--secondary-color);
    font-size: 0.82rem;
}

/*  Recipient history modal  */

/* Sized to its content: a handful of events, not a form, so it keeps the 220px tinted column but
   not the 860px width the wider two tone forms need. */
.modal-content.srh-modal.modal-two-tone.modal-two-tone-question-wrap {
    width: min(620px, 94vw);
}

/* Name reads first, the address sits under it smaller. The address breaks after its @ first, and
   only falls back to anywhere when one half alone is still wider than the column. */
.srh-modal .modal-subtitle {
    margin-top: 12px;
}

.srh-name {
    display: block;
    color: var(--font-color);
    font-weight: 700;
}

.srh-email {
    display: block;
    margin-top: 3px;
    font-size: 0.82rem;
    overflow-wrap: anywhere;
}

.srh-events {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Label left, timestamp right, with any detail wrapping onto its own line underneath */
.srh-event {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: baseline;
    gap: 4px 12px;
    padding: 9px 2px;
    border-bottom: 1px solid var(--accent-color);
}

.srh-event:last-child {
    border-bottom: none;
}

.srh-event-label {
    font-weight: 700;
    color: var(--font-color);
}

.srh-event-when {
    color: var(--secondary-color);
    font-size: 0.87rem;
    white-space: nowrap;
}

.srh-event-detail {
    grid-column: 1 / -1;
    color: var(--secondary-color);
    font-size: 0.83rem;
}

.srh-empty {
    padding: 14px 2px;
    color: var(--secondary-color);
    font-style: italic;
}

/* The button row sits outside a .modal-form here, which is what usually carries this gap. The two
   tone right column sets its own margin, so this only needs to beat it on specificity. */
.srh-modal .modal-two-tone-question-right .project-button-row {
    margin-top: 18px;
}

/*  Toasts  */

/* Bottom right, above everything but below a modal: a toast reports something that happened and
   must never cover what the user is working on. pointer-events on the container is off so the gap
   between toasts does not swallow clicks. */
.caddy-toast-container {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 1000;
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: min(360px, calc(100vw - 36px));
    pointer-events: none;
}

.caddy-toast {
    pointer-events: auto;
    padding: 11px 14px;
    border-radius: 10px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--font-color);
    background: var(--sub-background-color);
    border: 1px solid var(--accent-color);
    box-shadow: 0 8px 24px var(--shadow);
    cursor: pointer;
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.caddy-toast.is-visible {
    opacity: 1;
    transform: translateY(0);
}

.caddy-toast-info {
    border-left: 4px solid var(--primary-color);
}

.caddy-toast-warning {
    border-left: 4px solid #d9a300;
}

/*  Second modal layer  */

/* Hosts a modal opened from inside another one, so the first stays put underneath. Lives here
   rather than in a page stylesheet: any page with a modal can need the second layer. */
.modal.modal-overlay-2 {
    z-index: 1100;
}

/*  Shared entity picker: search + filter button, scrollable multiselect list  */

/* Moved here from sales.css so it loads on every page with a modal, not just /sales:
   the service signature email modal uses it for its recipient list. */
#saa-prev, #saa-next {
    margin-top: 0;
}

/* Attendee / company picker modal. The list keeps a consistent height (so the
   modal feels roomy) while the modal itself sizes to content, avoiding an empty
   dark gap when the filter narrows results. */
/* Search + filter button toolbar (invite-style) */
.saa-toolbar {
    display: flex;
    gap: 8px;
    align-items: center;
}
.saa-toolbar #saa-search {
    flex: 1 1 auto;
    min-width: 0;
}
.saa-filter-wrap {
    position: relative;
    flex: 0 0 auto;
}
.saa-filter-btn {
    position: relative;
    margin-top: 0;
    /* Matches .saa-add-btn: block level so the button has no text baseline to sit on */
    display: block;
    line-height: 0;
    width: 40px;
    min-width: 40px !important;
    height: 40px;
    border: 1px solid var(--primary-accent-color);
    border-radius: 10px;
    background-color: color-mix(in srgb, var(--secondary-accent-color) 18%, var(--background-color));
    background-image: url("/caddy/images/icons/filter/light-filter.png");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 18px 18px;
    cursor: pointer;
}
.saa-filter-btn:hover,
.saa-filter-btn.is-open {
    border-color: var(--primary-color) !important;
    background-color: var(--secondary-accent-color) !important;
}
.saa-filter-btn.has-filters::after {
    content: "";
    position: absolute;
    top: 4px;
    right: 4px;
    width: 8px;
    height: 8px;
    border-radius: 999px;
    background: var(--secondary-color);
}
.saa-filter-menu {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 60;
    min-width: 240px;
    border: 1px solid var(--accent-color);
    border-radius: 12px;
    background: var(--background-color);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.24);
}
.saa-filter-menu.hidden {
    display: none;
}
.saa-filter-menu-inner {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 14px;
}
.saa-filter-label {
    display: block;
    margin-bottom: 4px;
    color: var(--primary-color);
    font-size: 0.78rem;
    font-weight: 800;
    letter-spacing: 0.4px;
    text-transform: uppercase;
}
.saa-filter-menu-actions {
    display: flex;
    justify-content: flex-end;
}
.saa-clear-filters {
    font-family: inherit;
    font-weight: 600;
    font-size: 13px;
    padding: 6px 12px;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    background: var(--sub-background-color);
    color: var(--font-color);
    cursor: pointer;
}
.saa-clear-filters:hover {
    background: var(--accent-color);
}
.saa-filter {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 0.88rem;
    margin-top: 8px;
}
.saa-filter input[type="checkbox"] {
    width: auto;
    min-width: 0 !important;
    flex: 0 0 auto;
    margin: 0;
}
.saa-list {
    min-height: 360px;
    max-height: 420px;
    overflow-y: auto;
    border: 1px solid var(--accent-color);
    border-radius: 8px;
    margin-top: 8px;
}
/* modals.css loads after this file, so its ".modal-content label { display:block }"
   and ".modal-form input { margin-top }" would win on load order and specificity.
   Every rule here is scoped under .modal-content to outrank them. */
.modal-content label.saa-row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-top: 0;
    padding: 8px 11px;
    border-bottom: 1px solid var(--accent-color);
    font-weight: 400;
    cursor: pointer;
}
.modal-content label.saa-row:has(.saa-cb:checked) {
    background: color-mix(in srgb, var(--primary-color) 10%, transparent);
}
.modal-content label.saa-row:last-child {
    border-bottom: none;
}
/* Checkbox stays a small box on the left, inline with the name. Beats the global
   modal input min-width:96.5% and the .modal-form input margin-top that would
   otherwise size it up and drop it onto its own line. */
.modal-content .saa-row input[type="checkbox"] {
    width: 13px;
    min-width: 0;
    max-width: 13px;
    height: 13px;
    padding: 0;
    flex: 0 0 auto;
    margin: 1px 0 0 0;
}
/* Column wrapper so the muted meta line sits under the name line. min-width:0
   lets it shrink past the meta line's long unbroken emails instead of
   overflowing the row and pushing the checkbox onto its own line. */
.modal-content .saa-row .saa-body {
    display: block;
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
}
/* Line 1 keeps the old row layout: name left, company pushed right */
.modal-content .saa-row .saa-line {
    display: flex;
    align-items: baseline;
    min-width: 0;
}
.modal-content .saa-row .saa-name {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.modal-content .saa-row .saa-sub {
    color: var(--secondary-color);
    font-size: 0.82rem;
    margin-left: auto;
    padding-left: 16px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 0 1 auto;
}
/* Muted second line: phone/email for people, city/zip for companies */
.modal-content .saa-row .saa-meta {
    display: block;
    margin-top: 2px;
    color: var(--secondary-color);
    font-size: 0.8rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.saa-empty {
    padding: 14px;
    color: var(--secondary-color);
    font-style: italic;
    text-align: center;
}
.saa-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin-top: 10px;
    min-height: 20px;
}
.saa-pager button {
    font-family: inherit !important;
    font-weight: 600 !important;
    font-size: 13px !important;
    padding: 5px 12px !important;
    border: 1px solid var(--accent-color) !important;
    border-radius: 7px !important;
    background: var(--sub-background-color) !important;
    color: var(--font-color) !important;
    cursor: pointer !important;
    margin-top: 0 !important;
}
.saa-pager button:disabled {
    opacity: 0.45;
    cursor: default;
}
.saa-page {
    font-size: 0.85rem;
    color: var(--font-color);
}
