/* ==========================================================================
   SECTION A — Brand color override
   Gull's compiled CSS hardcodes its purple (#639) directly into each
   Bootstrap/Gull selector rather than referencing a CSS variable, so we
   can't retheme it with a single :root change. This file re-declares the
   same selectors Gull uses, pointing them at BuildOne's tokens instead.
   Loaded AFTER lite-purple.min.css so the cascade wins.
   ========================================================================== */

a { color: var(--bo-primary); }

.btn-primary,
.btn-primary.disabled,
.btn-primary:disabled {
    color: #fff;
    background-color: var(--bo-primary);
    border-color: var(--bo-primary);
}
.btn-primary:hover,
.btn-outline-primary:hover {
    background: var(--bo-primary-dark);
    border-color: var(--bo-primary-dark);
    box-shadow: 0 8px 20px -8px rgba(var(--bo-primary-rgb), .6);
}
.btn-primary:focus,
.btn-outline-primary:focus {
    box-shadow: 0 0 0 3px rgba(var(--bo-primary-rgb), .25);
}
.btn-outline-primary {
    color: var(--bo-primary);
    border-color: var(--bo-primary);
}
.btn-outline-primary:not(:disabled):not(.disabled):active,
.btn-outline-primary.active,
.show > .btn-outline-primary.dropdown-toggle {
    color: #fff;
    background-color: var(--bo-primary);
    border-color: var(--bo-primary);
}
.btn-link { color: var(--bo-primary); }
.btn-raised.btn-raised-primary {
    background: var(--bo-primary);
    box-shadow: 0 4px 6px rgba(var(--bo-primary-rgb), .11), 0 1px 3px rgba(var(--bo-primary-rgb), .08);
}

.bg-primary { background-color: var(--bo-primary) !important; }
.text-primary { color: var(--bo-primary) !important; }
.border-primary { border-color: var(--bo-primary) !important; }
.border-bottom-primary { border-bottom: 1px solid var(--bo-primary); }
.border-bottom-dotted-primary { border-bottom: 1px dotted var(--bo-primary); }

.badge-primary { background-color: var(--bo-primary); }
.dropdown-item.active,
.dropdown-item:active { background-color: var(--bo-primary); }
.list-group-item.active { background-color: var(--bo-primary); border-color: var(--bo-primary); }
.page-link { color: var(--bo-primary); }
.page-item.active .page-link { background-color: var(--bo-primary); border-color: var(--bo-primary); }
.progress-bar { background-color: var(--bo-primary); }
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link { background-color: var(--bo-primary); }
.nav-tabs .nav-item .nav-link.active { border-bottom: 2px solid var(--bo-primary); }

.checkbox input:checked ~ .checkmark,
.radio input:checked ~ .checkmark,
.checkbox-primary input:checked ~ .checkmark,
.radio-primary input:checked ~ .checkmark,
.switch input:checked + .slider {
    background-color: var(--bo-primary) !important;
}
.checkbox-outline-primary .checkmark,
.radio-outline-primary .checkmark { border-color: var(--bo-primary); }
.checkbox-outline-primary .checkmark:after,
.radio-outline-primary .checkmark:after { border-color: var(--bo-primary); background: var(--bo-primary); }
.custom-control-input:checked ~ .custom-control-label:before,
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label:before,
.custom-radio .custom-control-input:checked ~ .custom-control-label:before {
    background-color: var(--bo-primary);
}

.purple, .sidebar-purple .sidebar-left { background: var(--bo-primary); }
.card-icon .lead, .card-icon [class^="i-"] { color: var(--bo-primary); }
.menu-icon-grid > a:hover { background: var(--bo-primary); color: #fff; }
.active-color { background-color: var(--bo-primary); color: #fff !important; }

body.dark-theme { background-color: var(--bo-dark); }

/* Status / pipeline stage badges — ready for use from Phase 6 onward */
.badge-status-new         { background-color: var(--bo-status-new); color: #fff; }
.badge-status-contacted   { background-color: var(--bo-status-contacted); color: #fff; }
.badge-status-qualified   { background-color: var(--bo-status-qualified); color: #fff; }
.badge-status-hot         { background-color: var(--bo-status-hot); color: #fff; }
.badge-status-sitevisit   { background-color: var(--bo-status-sitevisit); color: #fff; }
.badge-status-negotiation { background-color: var(--bo-status-negotiation); color: #212529; }
.badge-status-booking     { background-color: var(--bo-status-booking); color: #fff; }
.badge-status-won         { background-color: var(--bo-status-won); color: #fff; }
.badge-status-lost        { background-color: var(--bo-status-lost); color: #fff; }
.badge-status-hold        { background-color: var(--bo-status-hold); color: #212529; }
.badge-status-active      { background-color: var(--bo-success); color: #fff; }
.badge-status-inactive    { background-color: #94A3B8; color: #fff; }
.badge-status-new, .badge-status-contacted, .badge-status-qualified, .badge-status-hot,
.badge-status-sitevisit, .badge-status-negotiation, .badge-status-booking, .badge-status-won,
.badge-status-lost, .badge-status-hold, .badge-status-active, .badge-status-inactive {
    display: inline-block;
    font-weight: 600;
    font-size: 11.5px;
    letter-spacing: .02em;
    padding: .32em .7em;
    border-radius: 999px;
}


/* ==========================================================================
   SECTION B — Professional light-mode pass (SaaS CRM polish, Bigin-inspired)
   Applies to light mode only; dark mode keeps Gull's existing dark palette.
   ========================================================================== */

body {
    color: var(--bo-dark);
    -webkit-font-smoothing: antialiased;
}

.text-muted { color: var(--bo-text-muted) !important; }

/* Canvas behind cards — LIGHT MODE ONLY. Bug fix: this used to be
   unscoped with !important, which clobbered Gull's own
   `.dark-theme .main-content-wrap{background-color:#262c49}` rule and
   left a light-gray canvas showing through behind the dark header/cards.
   Scoping it like this lets dark mode fall back to Gull's own palette. */
body:not(.dark-theme) .main-content-wrap {
    background-color: var(--bo-bg) !important;
}

/* Header: flush with the very top and sides (no floating-card gap).
   Gull's own rule (`.app-admin-wrap.sidebar-full .main-content-wrap`)
   adds 1rem top / 2rem side padding around everything in this column,
   which is what was pushing the header down and insetting it. We drop
   the top padding entirely and pull the header out of the side padding
   with matching negative margins so it spans edge-to-edge, then give it
   its own matching internal padding so its *content* still lines up
   with the page content below it. */
.app-admin-wrap.layout-sidebar-vertical.sidebar-full .main-content-wrap {
    padding: 0 2rem !important;
    margin-top: 0 !important;
}
.main-content-wrap .main-header {
    position: sticky;
    top: 0;
    z-index: 95;
    margin: 0 -2rem 1.5rem !important;
    width: calc(100% + 4rem) !important;
    padding: 0 2rem;
    border-radius: 0 !important;
    border: none;
    border-bottom: 1px solid var(--bo-border);
    box-shadow: var(--bo-shadow-sm);
}
.dark-theme .main-content-wrap .main-header {
    border-bottom-color: rgba(255, 255, 255, .08);
}

/* Header icon buttons: consistent circular hover, evenly spaced */
.main-header .header-part-right {
    display: flex;
    align-items: center;
    gap: 4px;
}
.main-header .header-icon {
    color: var(--bo-text-muted);
    transition: background-color .15s ease, color .15s ease;
}
.main-header .header-icon:hover {
    background: var(--bo-bg);
    color: var(--bo-primary);
}

/* Cards: remove flat Bootstrap border, add real elevation */
.card {
    border: 1px solid var(--bo-border);
    border-radius: var(--bo-radius);
    box-shadow: var(--bo-shadow-sm);
}
.card .card-body { padding: 1.5rem; }
.card-title { font-weight: 700; letter-spacing: -.01em; }

/* Page title */
.breadcrumb h1 {
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--bo-dark);
}

/* Buttons: slightly rounder, clear accessible focus ring everywhere */
.btn {
    border-radius: var(--bo-radius-sm);
    font-weight: 600;
}
a:focus-visible,
button:focus-visible,
.btn:focus-visible,
input:focus-visible,
.nav-link:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(var(--bo-primary-rgb), .35);
}
.form-control:focus {
    border-color: var(--bo-primary);
    box-shadow: 0 0 0 3px rgba(var(--bo-primary-rgb), .15);
}

/* Thin, unobtrusive scrollbars (PerfectScrollbar) */
.ps__thumb-y, .ps__thumb-x { background-color: #CBD5E1 !important; }
.ps__rail-y:hover .ps__thumb-y, .ps__rail-x:hover .ps__thumb-x { background-color: #94A3B8 !important; }


/* ==========================================================================
   SECTION C — Sidebar redesign
   ========================================================================== */

.sidebar-panel {
    border-right: 1px solid var(--bo-border);
    box-shadow: none;
}

/* Brand lockup — height is pinned to EXACTLY match .main-header's 64px
   (via explicit height + flex centering, not padding math) so the
   sidebar's divider line and the header's bottom border land on the
   same horizontal line instead of stepping. */
.bo-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 64px;
    padding: 0 20px;
    border-bottom: 1px solid var(--bo-border);
    margin-bottom: 8px;
}
.bo-brand-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    color: var(--bo-primary);
}
/* Sidebar-specific sizing — fits the 64px-tall header strip. The Login
   page sets its own larger size inline (48px), since it has more room
   for a bigger, more prominent mark. */
.bo-brand .bo-brand-mark i {
    font-size: 28px;
}
.dark-theme .bo-brand-mark {
    color: var(--bo-accent);
}
.bo-brand-name {
    font-size: 19px;
    font-weight: 800;
    letter-spacing: -.02em;
    color: var(--bo-dark);
}
/* Bug fix: this text was rendering dark-on-dark (invisible) in dark mode
   since it just inherited --bo-dark unconditionally. */
.dark-theme .bo-brand-name { color: #fff; }
.dark-theme .bo-brand { border-bottom-color: rgba(255, 255, 255, .08); }

/* Sidebar widened from Gull's default 240px to 260px: gives every nav
   label + badge combination (current and future) meaningfully more
   room, rather than fighting each one individually with copy edits.

   Bug fix (the "mobile view is completely mess" report): these were
   UNCONDITIONAL before — applying at every viewport size, including
   mobile. Gull's own CSS already tries to make the sidebar go
   off-canvas and main-content-wrap expand to fill the space below
   1150px, but this rule's higher specificity (3 classes vs. Gull's 1)
   meant it always won anyway, permanently reserving 260px of width
   for a sidebar that was supposed to be hidden — that's what produced
   the squeezed content column with a blank gap on the left. Scoping
   this to match Gull's own 1150px breakpoint lets Gull's existing,
   already-correct mobile behavior actually take effect. */
@media (min-width: 1151px) {
    .app-admin-wrap.sidebar-full .sidebar-panel { width: 260px; }
    .app-admin-wrap.sidebar-full .main-content-wrap { width: calc(100% - 260px); }
}

/* Gull's own off-canvas hide distance (left:-240px) only fully hides a
   240px-wide panel — ours is 260px, so 20px would still peek on
   screen. Matching the offset to our actual width. */
@media (max-width: 1150px) {
    .app-admin-wrap.sidebar-full .sidebar-panel { left: -260px; }
}

/* Nav items */
.side-nav .main-menu ul li a {
    display: flex;
    align-items: center;
    overflow: hidden;
    border-radius: var(--bo-radius-sm);
    margin: 0 10px 4px;
    padding: 0 12px !important;
    height: 40px !important;
    font-weight: 600;
    font-size: 14.5px;
    color: #475569 !important;
}
/* Bug fix: this had no white-space/overflow handling and no flex
   min-width reset, so a two-word label ("Users & Roles") next to a
   badge ("Admin only") wrapped inside the fixed 40px height instead of
   staying on one line — the garbled multi-line stack from the
   screenshot. min-width:0 is the key piece: flex items default to
   min-width:auto, which blocks shrinking below the text's natural
   width and is what defeats text-overflow inside a flex container. */
.side-nav .main-menu ul li a .item-name {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    min-width: 0;
    flex: 1 1 auto;
}
.side-nav .metismenu > li > a { margin: 0 10px 2px; }
.side-nav .main-menu ul li a:hover {
    background: var(--bo-bg);
    color: var(--bo-dark) !important;
}
.side-nav .main-menu ul li a i {
    color: #94A3B8;
    font-size: 17px !important;
    width: 20px;
    flex-shrink: 0;
    text-align: center;
}

/* Active item: filled pill, not just colored text */
.side-nav .metismenu > li > a.mm-active,
.side-nav .metismenu li > ul li > a.mm-active {
    background: rgba(var(--bo-primary-rgb), .1);
    color: var(--bo-primary) !important;
    font-weight: 700;
}
.side-nav .metismenu > li > a.mm-active i,
.side-nav .metismenu li > ul li > a.mm-active i {
    color: var(--bo-primary);
}

/* Disabled (not-yet-built) nav items */
.side-nav .metismenu li > a.disabled {
    pointer-events: none;
    color: #B4BCC8 !important;
}
.side-nav .metismenu li > a.disabled i { color: #CBD5E1; }
.bo-phase-badge {
    margin-left: auto;
    flex-shrink: 0;
    white-space: nowrap;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .01em;
    color: #94A3B8;
    background: var(--bo-bg);
    border: 1px solid var(--bo-border);
    border-radius: 999px;
    padding: 1px 6px;
    white-space: nowrap;
}

/* Parent-item collapse arrow: metisMenu draws it with `border-color: currentColor`
   by default, so it already follows the link's text color set above — no
   separate override needed here. */


/* ==========================================================================
   SECTION D — Header user-info chip (account settings / credentials / sign out)
   UI shell only — becomes live once Phase 1 (Authentication) lands. Every
   action inside is visibly disabled and phase-tagged, same convention as
   the sidebar's "Phase X" items.
   ========================================================================== */

.bo-header-divider {
    width: 1px;
    height: 24px;
    background: var(--bo-border);
    margin: 0 8px;
    flex-shrink: 0;
}
.dark-theme .bo-header-divider { background: rgba(255, 255, 255, .12); }

.bo-user-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 10px 5px 5px;
    border-radius: 999px;
    cursor: pointer;
    transition: background-color .15s ease;
}
.bo-user-chip:hover,
.bo-user-chip[aria-expanded="true"] { background: var(--bo-bg); }
.dark-theme .bo-user-chip:hover,
.dark-theme .bo-user-chip[aria-expanded="true"] { background: rgba(255, 255, 255, .06); }

.bo-user-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--bo-primary), var(--bo-accent));
    color: #fff;
    font-weight: 700;
    font-size: 13px;
}
.bo-user-name {
    font-weight: 600;
    font-size: 14px;
    color: var(--bo-dark);
}
.dark-theme .bo-user-name { color: #fff; }
.bo-user-caret { font-size: 10px; color: var(--bo-text-muted); }

.bo-user-menu {
    min-width: 240px;
    padding: 8px 0;
    border-radius: var(--bo-radius);
    border: 1px solid var(--bo-border);
    box-shadow: var(--bo-shadow);
}
.bo-user-menu .dropdown-header {
    font-size: 12px;
    color: var(--bo-text-muted);
    padding: 4px 16px 8px;
}
.bo-user-menu .dropdown-item {
    display: flex;
    align-items: center;
    font-size: 14px;
    padding: 9px 16px;
}
.bo-user-menu .dropdown-item:hover {
    background: var(--bo-bg);
}
.bo-user-menu .dropdown-item.disabled {
    pointer-events: none;
    opacity: .55;
}
/* Bug fix: icon and text were touching with no gap at all. */
.bo-user-menu .dropdown-item i {
    width: 18px;
    margin-right: 10px;
    text-align: center;
    color: var(--bo-text-muted);
}
.bo-user-menu .bo-phase-badge { margin-left: auto; }

/* Fix: <button> doesn't default to pointer the way .btn does — the
   Sign-out button just looked non-clickable. */
.bo-user-menu .dropdown-item { cursor: pointer; }
.bo-user-menu button.dropdown-item {
    background: transparent;
    border: 0;
    width: 100%;
    text-align: left;
    font-family: inherit;
    font-size: inherit;
}

/* Fix: Gull's dark-theme only styles .dropdown-item on :hover/:focus,
   never the resting state, so resting text stayed light-mode-dark
   (#47404f) on a dark navy dropdown — invisible until hovered. This
   covers all three menu items, not just Sign out (the other two just
   still showed their visible phase-badge pill, masking the same bug). */
.dark-theme .bo-user-menu .dropdown-item { color: #c2c6dc; }
.dark-theme .bo-user-menu .dropdown-item:hover { color: #fff; background: rgba(255, 255, 255, .06); }
.dark-theme .bo-user-menu { border-color: rgba(255, 255, 255, .1); }

.bo-role-hint {
    background: var(--bo-bg);
    border: 1px solid var(--bo-border);
    border-radius: var(--bo-radius-sm);
    padding: 10px 12px;
    font-size: 12.5px;
    color: var(--bo-text-muted);
}
.bo-role-hint strong { color: var(--bo-dark); }
.dark-theme .bo-role-hint {
    background: rgba(255, 255, 255, .04);
    border-color: rgba(255, 255, 255, .1);
    color: #c2c6dc;
}
.dark-theme .bo-role-hint strong { color: #fff; }


/* ==========================================================================
   SECTION E — Hover artifact fix + full dark-mode parity audit
   Gull ships NO .dark-theme rules at all for .side-nav, .text-muted, .ps__
   (scrollbar) or .breadcrumb, which is how the dark-on-dark "Dashboard"
   title bug happened — anything we color without an explicit dark
   counterpart silently leaks through unchanged. This section is a
   deliberate, complete pass rather than another one-off patch.
   ========================================================================== */

/* Gull's leftover decorative hover glow on parent nav items: a purple,
   36px-tall slide-in panel built for the old row height. We already have
   our own clean hover treatment on the link itself, so this is pure
   off-brand, misaligned noise now — remove it outright. */
.Ul_li--hover:before,
.Ul_li--hover:hover:before {
    display: none !important;
}

/* Sidebar nav hover/title text in dark mode */
.dark-theme .side-nav .main-menu ul li a { color: #c2c6dc !important; }
.dark-theme .side-nav .main-menu ul li a:hover {
    background: rgba(255, 255, 255, .06);
    color: #fff !important;
}
.dark-theme .side-nav .main-menu ul li a i { color: #8891ab; }
.dark-theme .sidebar-panel { border-right-color: rgba(255, 255, 255, .08); }

/* Header icons: no dark-mode base color existed before, so this was
   whatever --bo-text-muted resolved to, unconfirmed against the dark
   background — pin it explicitly instead of leaving it to chance. */
.dark-theme .main-header .header-icon { color: #c2c6dc; }
.dark-theme .main-header .header-icon:hover { color: #fff; }

/* Page title (the actual bug from your screenshot) */
.dark-theme .breadcrumb h1 { color: #fff; }

/* Muted text: Gull's own text color for dark mode is #c2c6dc, but that's
   only applied via `.main-content-wrap{color:#c2c6dc!important}` — our
   `.text-muted` rule carries `!important` too and can still end up too
   dim on navy. Lighten it specifically for dark mode. */
.dark-theme .text-muted { color: #94A3B8 !important; }
.dark-theme body { color: #c2c6dc; }

/* Scrollbar thumb: our light-gray thumb was showing unchanged on the
   dark track since Gull has no dark rule for PerfectScrollbar at all. */
.dark-theme .ps__thumb-y, .dark-theme .ps__thumb-x { background-color: rgba(255, 255, 255, .2) !important; }
.dark-theme .ps__rail-y:hover .ps__thumb-y, .dark-theme .ps__rail-x:hover .ps__thumb-x { background-color: rgba(255, 255, 255, .35) !important; }

/* Card border: Gull's own dark rule handles the card's background/text,
   but not our added border, which was showing as a pale ring. */
.dark-theme .card { border-color: rgba(255, 255, 255, .08); }


/* ==========================================================================
   SECTION F — Form readability in dark mode (Create/Edit Client bug)
   Confirmed root cause in the actual compiled CSS:
     .dark-theme input{background:#262c49!important}  <- forces dark bg
     .form-control{color:#47404f}                      <- but text stays
                                                            light-mode-dark
   Gull sets the input's BACKGROUND for dark mode but never repaints the
   TEXT color to match, so typed/placeholder text was dark-on-dark. Same
   story for <label> — zero .dark-theme rule exists for it anywhere.
   ========================================================================== */

.dark-theme label { color: #c2c6dc; }
/* Matches Gull's own `.dark-theme input{background:#262c49!important}` at
   the same tag-level scope (not just .form-control) — DataTables' search
   box, for instance, isn't a .form-control and would otherwise still hit
   the same dark-on-dark bug. */
.dark-theme input { color: #c2c6dc !important; }
/* Bug fix: `input` as a tag selector only matches <input> elements —
   <select> and <textarea> were never covered by this or by Gull's own
   equivalent rule, so they stayed light-mode white (the unreadable
   "Facing"/Status dropdowns and any textarea in dark mode). */
.dark-theme select.form-control,
.dark-theme textarea.form-control {
    background: #262c49 !important;
    color: #c2c6dc !important;
    border-color: #10163a !important;
}
/* The OPEN dropdown list of a native <select> (the popup showing
   "Available", etc.) is rendered by the OS/browser itself, not by our
   CSS — background-color/color on <option> has partial, inconsistent
   browser support and can't be fully guaranteed cross-browser. This is
   a genuine platform limitation, not something left unfixed. */
.dark-theme select.form-control option {
    background: #262c49;
    color: #c2c6dc;
}
.dark-theme .form-control::placeholder { color: #8891ab; opacity: 1; }
.dark-theme .form-control:focus { color: #fff; }
.dark-theme .card-title { color: #fff; }

/* Client-side validation styling (jQuery Unobtrusive Validation, added
   this round) — written for both themes from the start rather than
   waiting to find the dark-mode gap later. */
.input-validation-error { border-color: var(--bo-danger) !important; }
.field-validation-error {
    display: block;
    color: var(--bo-danger);
    font-size: 12.5px;
    margin-top: 4px;
}
.dark-theme .field-validation-error { color: #ff9b9b; }
.validation-summary-errors ul { margin-bottom: 0; padding-left: 18px; }


/* ==========================================================================
   SECTION G — DataTables dark-mode coverage
   Confirmed: Gull's compiled CSS has ZERO rules touching DataTables at
   all (light or dark) — it only ever loaded datatables.min.css as a
   separate, untouched vendor stylesheet. Covering it fully now that
   Phase 2 is the first real use, rather than one piece at a time.
   ========================================================================== */

.dark-theme .dataTables_wrapper .dataTables_length,
.dark-theme .dataTables_wrapper .dataTables_filter,
.dark-theme .dataTables_wrapper .dataTables_info,
.dark-theme .dataTables_wrapper .dataTables_processing {
    color: #c2c6dc;
}
.dark-theme .dataTables_wrapper .dataTables_paginate .paginate_button {
    color: #c2c6dc !important;
    border-color: transparent;
}
.dark-theme .dataTables_wrapper .dataTables_paginate .paginate_button.current {
    background: var(--bo-primary) !important;
    border-color: var(--bo-primary) !important;
    color: #fff !important;
}
.dark-theme .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
    background: rgba(255, 255, 255, .08) !important;
    color: #fff !important;
    border-color: transparent !important;
}
.dark-theme table.dataTable thead th,
.dark-theme table.dataTable thead td {
    color: #fff;
    border-bottom-color: rgba(255, 255, 255, .15);
}
.dark-theme table.dataTable tbody td {
    border-color: rgba(255, 255, 255, .08);
    color: #c2c6dc;
}
.dark-theme .dt-buttons .btn { color: #c2c6dc; }

/* Export button row: DataTables' Buttons extension wraps generated
   buttons in a plain .dt-buttons container with no built-in Bootstrap
   .btn-group fusion or gap in this build, so adjacent buttons (Copy,
   CSV, Excel, PDF, Print, Columns) were rendering flush against each
   other with no visible separation. */
.dt-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.dt-buttons .btn { margin: 0; }


/* ==========================================================================
   SECTION J — Professional DataTables styling (Phase 3)
   Applies globally to every DataTable, current (Clients, Users) and
   future — write once, matches BuildOne's brand language everywhere
   instead of Bootstrap/DataTables' plain defaults.
   ========================================================================== */

/* Bug fix: the border used to be on .table-responsive, but DataTables
   inserts its Buttons/search toolbar and length/pagination row as
   SIBLINGS of the table inside that same div — so the border wrapped
   the whole toolbar too, which read as "a box around the buttons".
   Applying the border to the table itself instead, and giving up on
   rounded corners for it (unreliable across browsers on a bordered
   <table> anyway, and a plain rectangular grid is the more
   conventional, "standard" look for a data table regardless). */
table.dataTable {
    border-collapse: collapse !important;
    margin-bottom: 0 !important;
    border: 1px solid var(--bo-border);
}
/* Visual gap between the toolbar row and the table itself */
.dataTables_wrapper > .row:first-child,
.dt-buttons {
    margin-bottom: 14px;
}

/* Header row: subtle tint + bold uppercase small labels, modern-SaaS style.
   Made noticeably more compact (smaller font/padding) so tables fit their
   card width more often without needing the horizontal scrollbar. */
table.dataTable thead th {
    background: var(--bo-bg);
    color: var(--bo-text-muted);
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    padding: 8px 10px !important;
    white-space: nowrap;
}
table.dataTable thead th.sorting_asc,
table.dataTable thead th.sorting_desc {
    color: var(--bo-primary);
}

/* Full bordered grid — every cell, both directions */
table.dataTable thead th,
table.dataTable tbody td {
    border: 1px solid var(--bo-border) !important;
}

table.dataTable tbody td {
    padding: 7px 10px !important;
    vertical-align: middle;
    font-size: 12.5px;
}
table.dataTable.table-hover tbody tr:hover td {
    background: rgba(var(--bo-primary-rgb), .04);
}

/* Bug fix: action buttons (Edit/Deactivate/Copy, etc.) were wrapping
   onto separate lines when the Actions column was narrower than their
   combined width, which looked like they were "stuck together"
   vertically — the horizontal gap fix alone doesn't help once they've
   wrapped. Actions is always the last column in every table in this
   app, so keeping it on one line here is a safe, global rule. */
table.dataTable td:last-child {
    white-space: nowrap;
}

/* Search box: match BuildOne's rounded input language instead of the
   plain square Bootstrap default */
.dataTables_wrapper .dataTables_filter input {
    border-radius: 999px;
    border: 1px solid var(--bo-border);
    padding: 6px 16px;
    font-size: 13.5px;
    min-width: 220px;
    margin-left: 0 !important;
}
.dataTables_wrapper .dataTables_filter input:focus {
    border-color: var(--bo-primary);
    box-shadow: 0 0 0 3px rgba(var(--bo-primary-rgb), .15);
    outline: none;
}

/* Pagination: rounded pill buttons instead of square Bootstrap defaults */
.dataTables_wrapper .dataTables_paginate .paginate_button {
    border-radius: 8px !important;
    margin-left: 4px !important;
    border: 1px solid transparent !important;
    padding: 5px 12px !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.current,
.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
    background: var(--bo-primary) !important;
    border-color: var(--bo-primary) !important;
    color: #fff !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button:hover:not(.current) {
    background: var(--bo-bg) !important;
    border-color: var(--bo-border) !important;
}
.dataTables_wrapper .dataTables_info { color: var(--bo-text-muted); font-size: 13px; }
.dataTables_wrapper .dataTables_length select {
    border-radius: var(--bo-radius-sm);
    border: 1px solid var(--bo-border);
    padding: 3px 8px;
}

/* Dark mode — same discipline as everywhere else: written alongside the
   light-mode rules, not bolted on after a bug report. */
.dark-theme table.dataTable thead th {
    background: rgba(255, 255, 255, .03);
    color: #94A3B8;
}
.dark-theme table.dataTable thead th.sorting_asc,
.dark-theme table.dataTable thead th.sorting_desc {
    color: #fff;
}
.dark-theme table.dataTable.table-hover tbody tr:hover td {
    background: rgba(255, 255, 255, .04);
}
.dark-theme .dataTables_wrapper .dataTables_filter input {
    border-color: rgba(255, 255, 255, .12);
}
.dark-theme .dataTables_wrapper .dataTables_paginate .paginate_button:hover:not(.current) {
    background: rgba(255, 255, 255, .06) !important;
    border-color: transparent !important;
}
.dark-theme .dataTables_wrapper .dataTables_length select {
    border-color: rgba(255, 255, 255, .12);
}
/* These need !important specifically because the light-mode rule above
   uses the `border` shorthand with !important — a non-important
   longhand override (even from a more specific selector) loses to that
   regardless of specificity, so it has to match in kind here. */
/* Stale reference fixed: border moved from .table-responsive to the
   table itself (see Section J), so the dark override needs to target
   the same element now. */
.dark-theme table.dataTable { border-color: rgba(255, 255, 255, .12); }
.dark-theme table.dataTable thead th,
.dark-theme table.dataTable tbody td {
    border-color: rgba(255, 255, 255, .12) !important;
}


/* ==========================================================================
   SECTION K — Round 2 fixes: file input height, action-button spacing,
   Sr No. column, stale table-responsive border reference
   ========================================================================== */

/* Bug fix #2: Bootstrap's .form-control padding/line-height is tuned for
   text inputs; a native <input type="file"> ignores that line-height,
   so its own "Choose File" button pinned itself to the bottom of the
   taller box instead of centering. height:auto lets the control size
   to its own natural content instead of the text-input height. */
input[type="file"].form-control {
    height: auto;
    padding: .5rem .75rem;
}

/* Bug fix #4: action buttons in table cells (Edit/Deactivate, etc.) had
   no gap and rendered flush against each other. */
table.dataTable td .btn + .btn,
table.dataTable td .btn + form,
table.dataTable td form + .btn {
    margin-left: 6px;
}

/* Sr No. column: numeric, centered, never sortable, never exported as
   a "real" data column visually distinct from the rest */
table.dataTable td.bo-srno,
table.dataTable th.bo-srno {
    text-align: center;
    color: var(--bo-text-muted);
    width: 50px;
}

/* Safety net: guarantee horizontal scroll works no matter how DataTables
   restructures the DOM around the table (it inserts its own toolbar/
   pagination elements as siblings, which has already caused one bug in
   this file). Applied to both the wrapper we control AND the outermost
   container DataTables itself always creates, regardless of custom
   `dom` strings, so a table wider than its card can never be silently
   clipped with no way to reach the cut-off columns again. */
.table-responsive {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
}
.dataTables_wrapper {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}


/* ==========================================================================
   SECTION L — Sidebar toggle: desktop collapse vs. mobile off-canvas
   These are two DIFFERENT mechanisms for two different needs, kept
   deliberately separate rather than trying to force one to do both:
   - Desktop (>1150px): sidebar is visible by default; the toggle HIDES
     it entirely to reclaim width (useful for wide layouts like Pipeline).
   - Mobile (<=1150px): sidebar is off-canvas by default (Gull's own
     existing behavior, confirmed working — it just had no JS to
     reveal it again); the toggle SHOWS it as a temporary overlay.
   !important is deliberate in both cases, not a hack: these are state
   overrides that must always win regardless of Gull's own specificity.
   ========================================================================== */
@media (min-width: 1151px) {
    body.bo-sidebar-collapsed .sidebar-panel {
        display: none !important;
    }
    body.bo-sidebar-collapsed .main-content-wrap {
        width: 100% !important;
    }
}

/* Mobile off-canvas reveal — reuses Gull's own .sidebar-switch-open
   rule (it already existed in Gull's CSS with exactly this behavior,
   left:0!important, but nothing in the shipped JS ever actually added
   the class for this layout variant — the toggle button existed
   visually but did nothing on mobile). Our own JS adds/removes this
   class on click instead of inventing a new mechanism. */
@media (max-width: 1150px) {
    .app-admin-wrap.sidebar-full .sidebar-panel.sidebar-switch-open {
        left: 0 !important;
        z-index: 1100;
    }

    /* Bug fix (header icons not clickable on mobile): confirmed, not
       just suspected — Gull's own .switch-overlay is position:fixed,
       z-index:20000 (far above anything else on the page), spans
       nearly the full viewport height, and covers width:calc(100% -
       240px) anchored to the RIGHT edge. On a phone-width screen
       that's exactly the region where the header's dark-mode toggle
       and user avatar sit, and since this rule applies unconditionally
       (not tied to any state class), it silently intercepted every
       click there regardless of whether anything else was open.
       pointer-events:none removes only the click-interception —
       nothing else about the element changes, and Gull's own file is
       still untouched. */
    .switch-overlay {
        pointer-events: none;
    }
}

/* Backdrop: tap outside the open mobile sidebar to close it. Our own
   class, not Gull's ambiguous .switch-overlay (which carries a resize
   cursor and unclear original purpose — not worth the risk of reusing
   something not fully understood for a different job). */
.bo-sidebar-backdrop {
    display: none;
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(0, 0, 0, .4);
    z-index: 1090;
}
.bo-sidebar-backdrop.show {
    display: block;
}


/* ==========================================================================
   SECTION M — Pipeline board
   Columns have a bounded height with their OWN internal scroll for
   cards, so the page never needs vertical scrolling just to reach the
   horizontal scrollbar for the columns themselves — that's what made
   the board difficult to use before (scroll down, THEN scroll sideways).
   ========================================================================== */

#bo-pipeline-scroll-top {
    overflow-x: auto;
    overflow-y: hidden;
    height: 16px;
    margin-bottom: 4px;
}
#bo-pipeline-scroll-top-spacer {
    height: 1px;
}

#bo-pipeline-board {
    display: flex;
    gap: 14px;
    overflow-x: auto;
    padding-bottom: 12px;
}

.bo-pipeline-column {
    min-width: 280px;
    max-width: 280px;
    flex-shrink: 0;
    background: var(--bo-white);
    border: 1px solid var(--bo-border);
    border-radius: var(--bo-radius);
    display: flex;
    flex-direction: column;
    /* Bounded height is the key fix: columns scroll their OWN cards
       instead of pushing the whole page taller. */
    max-height: calc(100vh - 280px);
}

.bo-pipeline-column-header {
    padding: 10px 14px;
    border-top: 3px solid var(--bo-border);
    border-bottom: 1px solid var(--bo-border);
    border-radius: var(--bo-radius) var(--bo-radius) 0 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 13px;
    flex-shrink: 0;
}

.bo-pipeline-column-body {
    padding: 10px;
    overflow-y: auto;
    flex: 1 1 auto;
}

.bo-pipeline-card {
    background: var(--bo-bg);
    border: 1px solid var(--bo-border);
    border-radius: var(--bo-radius-sm);
    padding: 10px;
    margin-bottom: 10px;
    transition: box-shadow .15s ease, transform .15s ease;
}
.bo-pipeline-card:hover {
    box-shadow: var(--bo-shadow);
    transform: translateY(-1px);
}
.bo-pipeline-card:last-child { margin-bottom: 0; }
.bo-pipeline-card .bo-stage-select {
    font-size: 12px;
    padding: 3px 8px;
    height: auto;
}

.dark-theme .bo-pipeline-column {
    background: #10163a;
    border-color: rgba(255, 255, 255, .1);
}
.dark-theme .bo-pipeline-column-header {
    border-bottom-color: rgba(255, 255, 255, .1);
    color: #fff;
}
.dark-theme .bo-pipeline-card {
    background: rgba(255, 255, 255, .04);
    border-color: rgba(255, 255, 255, .08);
    color: #c2c6dc;
}
