/* ==========================================================================
   Theme Orbit — Perfex CRM admin reskin ("Orbit ERP" design system)
   Targets the ACTUAL selectors Perfex 3.2.0 renders (same selector map
   verified live for the theme_v1 module): #header/#logo/#top_search/
   .navbar-nav for the topbar, #menu.sidebar/.metis-menu/.menu-item-*/
   .menu-icon/.menu-text for the sidebar, #wrapper/.content/.row/
   .col-md-* for page bodies, .panel_s/.panel-body/.panel-footer for
   cards, plus stock Bootstrap 3 + DataTables classes for buttons/forms/
   tables/modals/alerts. Nothing here replaces Perfex's own markup, JS,
   AJAX, or DataTables config — presentation only.
   ========================================================================== */
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=Inter:wght@400;500;600;700&display=swap');

/* ---- Base ----
   Wash intensity matches SampleTemplate.html's own light-mode values
   (14-16% opacity), tied to the two admin-configurable brand colors
   instead of the source's hardcoded pink/purple so it stays coherent
   if an admin picks different colors — same idea as the source, tuned
   to stay on-brand rather than diluted. */
body{
  background:
    radial-gradient(1000px 520px at 88% -8%, color-mix(in srgb, var(--o-c1) 16%, transparent), transparent),
    radial-gradient(900px 480px at -5% 8%, color-mix(in srgb, var(--o-c2) 15%, transparent), transparent),
    var(--o-bg-base) !important;
  font-family:var(--o-font-body);
  color:var(--o-text-hi);
  transition:background .3s ease, color .3s ease;
}
/* Dark mode uses a single c1-only corner wash at 10% — verified against
   ThemeComponents.html's own body rule (that file defaults to dark
   theme, so this IS its actual shipped rule, not a derived guess):
   only one radial-gradient stop, no second c2 wash like light mode. */
[data-theme="dark"] body{
  background:
    radial-gradient(1200px 600px at 85% -10%, color-mix(in srgb, var(--o-c1) 10%, transparent), transparent),
    var(--o-bg-base) !important;
}
h1,h2,h3,h4,.page-title{font-family:var(--o-font-display); color:var(--o-text-hi);}
a{color:var(--o-c1); transition:color .12s ease;}
a:hover, a:focus{color:var(--o-text-hi);}
a:not(.btn):not(.navitem):not([class*="menu"]):not(.dropdown-menu a):not(.pagenums a):hover{text-decoration:underline;}
.text-muted{color:var(--o-text-low) !important;}

/* ---- Topbar (#header) ---- */
#header{
  background:color-mix(in srgb, var(--o-surface) 92%, transparent);
  backdrop-filter:blur(14px);
  border-bottom:1px solid var(--o-border);
  box-shadow:0 1px 0 rgba(255,255,255,.6) inset, 0 12px 28px -22px rgba(40,30,60,.30);
}
#header #search_input{
  border-radius:var(--o-radius-sm) !important;
  font-family:var(--o-font-body);
}
.navbar-nav > li > a{color:var(--o-text-mid);}
.navbar-nav > li > a:hover{color:var(--o-text-hi);}

/* ---- Light/dark mode toggle button ----
   Markup echoed by theme_orbit_mode_toggle_html() (helpers/
   theme_orbit_helper.php) via the real admin_navbar_end hook. Both
   icons always exist in the DOM; which one shows is pure CSS keyed
   off [data-theme] on <html> — no JS needed for the swap itself, only
   for setting that attribute + persisting the choice (theme_orbit.js). */
.header-theme-toggle > a{display:flex; align-items:center; justify-content:center; height:100%;}
.header-theme-toggle .to-icon-dark{display:none;}
[data-theme="dark"] .header-theme-toggle .to-icon-light{display:none;}
[data-theme="dark"] .header-theme-toggle .to-icon-dark{display:block;}
#header .dropdown-menu{
  background:var(--o-surface);
  border:1px solid var(--o-border-strong);
  border-radius:var(--o-radius-md);
  box-shadow:var(--o-shadow-soft);
  padding:6px;
}
#header .dropdown-menu > li > a{border-radius:10px; font-size:13px;}
#header .dropdown-menu > li > a:hover{background:var(--o-surface-2);}

/* ---- Sidebar (#menu.sidebar / metis-menu) ----
   Uses the --o-menu-* tokens (defined in tokens.css, defaulting to the
   same values as the app-wide tokens) rather than the app-wide tokens
   directly, so a future Menu Style feature could recolor the sidebar
   independently — same pattern as theme_v1. */
.sidebar{
  background:linear-gradient(180deg, var(--o-surface), var(--o-menu-bg));
  border-right:1px solid var(--o-border);
}
/* Found while verifying RTL (this is a real, staff-configurable
   per-user setting, not a hypothetical): core's own [dir="rtl"]
   .sidebar rule zeroes border-right and adds border-left using a
   hardcoded grey (#cbd5e1) instead of any theme-aware value — since
   that RTL selector is more specific than the bare .sidebar rule
   above, it wins in RTL mode and the sidebar's edge silently reverts
   to stock Perfex grey there. Re-themed. */
[dir="rtl"] .sidebar{border-left-color:var(--o-border);}
#menu.sidebar .sidebar-user-profile .profile{
  border-radius:var(--o-radius-sm) !important;
  box-shadow:var(--o-shadow-card);
  color:var(--o-menu-text);
}
#menu.sidebar .sidebar-user-profile .profile span{color:var(--o-menu-text) !important;}
ul.metis-menu > li > a{
  font-weight:600;
  font-size:13.5px;
  color:var(--o-menu-text);
  border-radius:12px;
  margin:2px 8px;
}
ul.metis-menu > li > a:hover{
  background:rgba(127,127,127,.12);
  color:var(--o-menu-active-text);
}
/* !important on background/color only (not the base link color above —
   that one must stay overridable by Setup > Theme Style's own "Sidebar
   Menu Links Color", which wins via #side-menu's ID specificity, not
   !important). Core Perfex has a higher-specificity rule targeting the
   active item specifically that silently wins over a same-shape
   selector without it — same specificity fight theme_v1 already solved. */
ul.metis-menu > li.active > a,
ul.metis-menu > li > a.active{
  background:linear-gradient(135deg, var(--o-c1-light), var(--o-c1)) !important;
  color:#fff !important;
  box-shadow:0 8px 18px -8px color-mix(in srgb, var(--o-c1) 65%, transparent), inset 0 1px 0 rgba(255,255,255,.25);
}
ul.metis-menu .menu-icon{color:var(--o-menu-text); width:16px; text-align:center; opacity:.75;}
ul.metis-menu > li.active > a .menu-icon,
ul.metis-menu > li > a.active .menu-icon{color:#fff !important; opacity:1;}
ul.metis-menu .badge{
  background:var(--o-surface-2) !important;
  color:var(--o-menu-text);
  border-radius:99px;
  font-weight:700;
}
ul.metis-menu > li.active > a .badge{background:rgba(255,255,255,.25) !important; color:#fff;}
ul.nav-second-level > li > a{
  color:var(--o-menu-text);
  font-size:12.5px;
  border-radius:10px;
  margin:1px 8px 1px 20px;
}
ul.nav-second-level > li > a:hover{background:rgba(127,127,127,.12); color:var(--o-menu-active-text);}
ul.nav-second-level > li.active > a{color:var(--o-c1); font-weight:600;}

/* ---- Page body (#wrapper / .content) ---- */
#wrapper > .content{padding-top:6px;}

/* ---- Cards (.panel_s — Perfex's actual card wrapper class) ---- */
.panel_s{
  background:linear-gradient(160deg, var(--o-surface), var(--o-bg-elevated) 160%);
  border:1px solid var(--o-border);
  border-radius:var(--o-radius-lg);
  box-shadow:var(--o-shadow-card);
}
/* background:transparent was missing here — .panel-footer right below
   already correctly has it, .panel-body never got the same treatment,
   a clear inconsistency in earlier work. Tailwind's compiled bundle
   hardcodes background-color:white on .panel-body (verified during
   the very first proactive bundle scan, way back — .panel,.panel-
   body,.panel_s{background-color:rgb(255 255 255...)}), and since
   .panel_s's own gradient is a background-image (painted below any
   background-color on the SAME element, but a child's opaque
   background-color still fully covers the parent's image within the
   child's own box) — .panel-body's white would sit on top of .panel_s's
   gradient wherever nothing else painted over it. Confirmed as a real,
   visible bug on the client portal's Files page (the "No Files Found"
   empty-state row stayed white); admin-side impact from the same rule
   was inconclusive to confirm via this tooling for a card with dense
   content, but the fix is safe regardless — transparent can't make
   anything worse, it only lets the correctly-dark .panel_s underneath
   show through everywhere .panel-body doesn't already have content
   painting over it. */
.panel_s .panel-body{padding:22px 24px; background:transparent;}
.panel_s .panel-footer{
  background:transparent;
  border-top:1px solid var(--o-border);
  border-radius:0 0 var(--o-radius-lg) var(--o-radius-lg);
}
.panel-table-full{border-radius:var(--o-radius-lg); overflow:hidden;}

/* ---- Dashboard KPI tiles (.top_stats_wrapper — verified live: the 4
   "Invoices Awaiting Payment / Converted Leads / Projects In Progress /
   Tasks Not Finished" cards at the top of the Dashboard). Core Perfex
   gives this its own hardcoded white/7px-radius card styling separate
   from .panel_s, so it needs its own rule — same card treatment as
   .panel_s for visual consistency. ---- */
.top_stats_wrapper{
  background:linear-gradient(160deg, var(--o-surface), var(--o-bg-elevated) 160%);
  border:1px solid var(--o-border);
  border-radius:var(--o-radius-md);
  box-shadow:var(--o-shadow-card);
}

/* ---- Dashboard KPI icon badges ----
   Each tile already renders a plain grey outline SVG icon before its
   title (verified live: .top_stats_wrapper > [flex row] > [title div] >
   svg.tw-w-6.tw-h-6...tw-text-neutral-600) — no markup change needed,
   just recoloring that existing icon into a gradient badge, the same
   motif as the mockup's .icon-orb. Descendant selector (not a strict
   child chain) so this survives minor internal restructuring of the
   title row. Per-tile color varies by the wrapping quick-stats-* class
   (verified live: invoices/leads/projects/tasks), same 4-color spread
   as the mockup's orb-c1/orb-c2/orb-success/orb-danger. Specificity
   (2 classes + type) beats the single-class Tailwind utilities
   (tw-w-6/tw-h-6/tw-mr-3/tw-text-neutral-600) setting the same
   properties, so no !important needed. */
.quick-stats-invoices .top_stats_wrapper svg,
.quick-stats-leads .top_stats_wrapper svg,
.quick-stats-projects .top_stats_wrapper svg,
.quick-stats-tasks .top_stats_wrapper svg{
  width:34px !important;
  height:34px !important;
  padding:8px;
  box-sizing:border-box;
  border-radius:12px;
  color:#fff;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.4), inset 0 -4px 8px rgba(0,0,0,.2), 0 8px 16px -8px rgba(0,0,0,.35);
}
/* margin kept separate from the shared block above and scoped to LTR
   only — found live while verifying RTL: Perfex's own markup already
   handles this correctly for both directions (the icon's real class
   list includes "tw-mr-3 rtl:tw-ml-3" — a Tailwind conditional variant
   that swaps the margin side in RTL on its own). An earlier version of
   this rule applied margin-right unconditionally with !important,
   which then stacked ON TOP of core's own rtl:tw-ml-3 in RTL mode
   instead of yielding to it — verified live: computed style showed
   12px margin on BOTH sides simultaneously in RTL, pushing the icon
   an extra 12px away from the card edge that wasn't in the original
   design. Scoping to :not([dir="rtl"]) lets core's own already-correct
   RTL handling take over untouched. */
:not([dir="rtl"]) .quick-stats-invoices .top_stats_wrapper svg,
:not([dir="rtl"]) .quick-stats-leads .top_stats_wrapper svg,
:not([dir="rtl"]) .quick-stats-projects .top_stats_wrapper svg,
:not([dir="rtl"]) .quick-stats-tasks .top_stats_wrapper svg{
  margin-right:12px;
}
.quick-stats-invoices .top_stats_wrapper svg{background:linear-gradient(150deg, var(--o-c1-light), var(--o-c1) 65%, var(--o-c1-dark));}
.quick-stats-leads .top_stats_wrapper svg{background:linear-gradient(150deg, #58E3AE, var(--o-success));}
.quick-stats-projects .top_stats_wrapper svg{background:linear-gradient(150deg, var(--o-c2-light), var(--o-c2) 65%, var(--o-c2-dark));}
.quick-stats-tasks .top_stats_wrapper svg{background:linear-gradient(150deg, #FF7C93, var(--o-danger));}

/* ---- Stock Bootstrap .panel (used by some pages, e.g. Accounting > Reports,
   instead of Perfex's own .panel_s) — same card treatment, different class. ---- */
.panel.panel-default{
  background:linear-gradient(160deg, var(--o-surface), var(--o-bg-elevated) 160%);
  border:1px solid var(--o-border);
  border-radius:var(--o-radius-lg);
  box-shadow:var(--o-shadow-card);
  overflow:hidden;
}
.panel-group{margin-bottom:20px;}
.panel-group .panel{margin-bottom:16px;}
/* .panel-heading/.panel-title are also used by kanban boards, pipelines,
   tickets, and other pages untested against this styling — scoped to
   .panel.panel-default only, same reasoning as .panel-body below. */
.panel.panel-default .panel-heading{
  background:var(--o-surface-2) !important;
  border-bottom:1px solid var(--o-border);
  padding:14px 22px;
}
.panel.panel-default .panel-heading .panel-title{
  font-family:var(--o-font-display);
  font-size:14px;
  font-weight:700;
  color:var(--o-text-hi);
}
/* Bare .panel-heading directly inside .panel_s (not .panel.panel-default) —
   found via repo grep + live dark-mode testing: this instance's compiled
   Tailwind bundle hardcodes a light rgb(249,250,251) background on the
   bare .panel-heading class, unscoped, app-wide. Real, currently-
   unthemed instances confirmed via source: invoices/record_payment_
   template.php, reports/leads.php (×3), settings/includes/sms.php —
   all direct children of .panel_s, no inline style.
   DELIBERATELY NO !important here — caught live: Kanban's column
   header (tasks/kan_ban.php) matches this exact selector too, and
   sets its per-status color via inline style from PHP. An earlier
   version of this rule used !important and broke that: a stylesheet
   rule with !important overrides even inline styles (only a plain,
   non-important rule correctly loses to inline styles) — verified
   live, the Kanban header rendered this theme's flat dark surface
   instead of its real status color until !important was removed here.
   Without !important, this rule still safely beats Tailwind's bare,
   non-important .panel-heading rule on specificity alone (2 classes >
   1), while correctly losing to Kanban's inline style as intended. */
.panel_s > .panel-heading{
  background:var(--o-surface-2);
  border-bottom:1px solid var(--o-border);
  padding:14px 22px;
}

/* Tailwind neutral-grey text utilities (tw-text-neutral-400 through
   -900), scoped to inside cards this theme already forces dark
   (.panel_s, .panel.panel-default) — found live on the client
   portal's invoice-preview page: labels like "Invoice Date:" use
   these utilities directly in the markup (verified: <span
   class="tw-font-medium tw-text-neutral-700">), and while the CARD
   itself correctly picks up this theme's dark background (confirmed
   via computed style — that part already worked), the label text's
   own hardcoded dark-grey color (tuned for a white card) went
   unreadable against it. These utilities are used FAR too broadly
   app-wide (any light-background context) to safely recolor
   everywhere, so deliberately scoped to only inside the cards this
   theme has already committed to darkening, not a global override.
   No !important: the source utility is a single class with no
   !important of its own, and this rule's 2-class descendant selector
   already beats it on plain specificity. */
.panel_s .tw-text-neutral-400, .panel.panel-default .tw-text-neutral-400,
.panel_s .tw-text-neutral-500, .panel.panel-default .tw-text-neutral-500,
.panel_s .tw-text-neutral-600, .panel.panel-default .tw-text-neutral-600{
  color:var(--o-text-mid);
}
.panel_s .tw-text-neutral-700, .panel.panel-default .tw-text-neutral-700,
.panel_s .tw-text-neutral-800, .panel.panel-default .tw-text-neutral-800,
.panel_s .tw-text-neutral-900, .panel.panel-default .tw-text-neutral-900{
  color:var(--o-text-hi);
}
/* Scoped to .panel.panel-default specifically — "panel-body"/"panel-heading"
   are class names Perfex's OWN .panel_s cards also use internally, so an
   unscoped rule here leaks into every other list page's row-action links
   and breaks their layout — same trap theme_v1 already ran into and
   documented. Verify no unscoped .panel-body / .panel-heading rule exists
   below this block. */
.panel.panel-default .panel-body{padding:20px 22px;}
.panel.panel-default .panel-body a{display:block;}
.panel.panel-default .panel-body a h4{
  font-family:var(--o-font-body);
  font-weight:700;
  font-size:13.5px;
  color:var(--o-c1);
  margin:0 0 2px;
}
.panel.panel-default .panel-body a:hover h4{color:var(--o-text-hi); text-decoration:underline;}
.panel.panel-default .panel-body .row > div{padding-top:14px; padding-bottom:14px;}
.panel.panel-default .panel-body p{
  font-size:12px;
  color:var(--o-text-low);
  font-weight:400;
  margin:0;
}

/* ---- Buttons ---- */
.btn{
  font-weight:600;
  border-radius:var(--o-radius-sm);
  transition:transform .12s ease, filter .15s ease;
}
.btn:active{transform:translateY(1px);}
.btn-primary{
  background:linear-gradient(180deg,var(--o-c1-light),var(--o-c1));
  border-color:transparent;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.3), 0 10px 20px -10px color-mix(in srgb, var(--o-c1) 65%, transparent);
}
.btn-primary:hover,.btn-primary:focus{filter:brightness(1.06); border-color:transparent;}
.btn-default{
  background:var(--o-surface);
  border-color:var(--o-border-strong);
  color:var(--o-text-hi);
  box-shadow:var(--o-shadow-card);
}
.btn-info{background:linear-gradient(180deg,#7FA6FF,var(--o-info)); border-color:transparent;}
.btn-success{background:linear-gradient(180deg,#6EDBA6,var(--o-success)); border-color:transparent;}
.btn-warning{background:linear-gradient(180deg,var(--o-c2-light),var(--o-c2)); border-color:transparent; color:#5A3A00;}
.btn-danger{background:linear-gradient(180deg,#FF8FA3,var(--o-danger)); border-color:transparent;}
.btn-icon{
  min-width:30px; min-height:30px;
  padding:5px 8px !important;
  border-radius:9px;
}
.btn-icon i{font-size:13px;}

/* ---- Forms ----
   background/color weren't set here before dark mode existed — with
   no override, inputs silently inherited Bootstrap's hardcoded white
   background + black text (invisible bug in light mode, but a glaring
   white box on a dark card once [data-theme="dark"] exists). Matches
   the mockup's own .input component (background:var(--bg-elev-3)) —
   mapped to --o-surface-2 here, the same token already used for every
   other "muted secondary surface" role in this file (hover states,
   badges), for consistency rather than introducing a new token. */
.form-control, select.form-control, textarea.form-control{
  background:var(--o-surface-2) !important;
  color:var(--o-text-hi) !important;
  border-radius:var(--o-radius-sm) !important;
  border-color:var(--o-border-strong) !important;
  box-shadow:none;
}
.form-control::placeholder{color:var(--o-text-low); opacity:1;}
.form-control:disabled, .form-control[readonly]{opacity:.65;}
/* Field LABELS ("Company", "VAT Number", etc.) had the same gap as the
   inputs above — found via the same proactive Tailwind-bundle scan:
   .control-label,label{color:rgb(75,85,99)}, unconditional, app-wide. */
.control-label, label{color:var(--o-text-mid);}
.form-control:focus{
  border-color:var(--o-c1);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--o-c1) 18%, transparent);
}
.bootstrap-select .btn{border-radius:var(--o-radius-sm) !important; border-color:var(--o-border-strong) !important;}
.bootstrap-select .dropdown-menu{border-radius:var(--o-radius-md); box-shadow:var(--o-shadow-soft);}

/* ---- Checkboxes/radios ----
   Perfex's actual checkbox widget (Bootstrap 3 "awesome-bootstrap-
   checkbox" pattern: .checkbox > input + label) hides the real <input>
   (opacity:0) and draws the visible box/checkmark entirely via
   label::before/::after — styling the <input> itself has no visible
   effect. Theme the real visible pseudo-elements instead. Same fix
   theme_v1 already verified live (glyph swap + padding trap). */
.checkbox label, .radio label{
  display:inline-block !important;
  min-width:17px;
  min-height:17px;
  padding-left:0 !important;
  position:relative;
}
.checkbox.mass_select_all_wrap{padding-left:20px !important;}
.checkbox label::before, .radio label::before{
  border-radius:5px;
  border:1.5px solid var(--o-text-low) !important;
  background:var(--o-surface) !important;
  left:0 !important;
  top:1px !important;
}
.checkbox input[type="checkbox"]:checked + label::before,
.checkbox input[type="radio"]:checked + label::before,
.radio input[type="checkbox"]:checked + label::before,
.radio input[type="radio"]:checked + label::before{
  background:linear-gradient(180deg,var(--o-c1-light),var(--o-c1)) !important;
  border-color:transparent !important;
}
.checkbox input[type="checkbox"]:checked + label::after,
.checkbox input[type="radio"]:checked + label::after{
  color:#fff !important;
  border-color:#fff !important;
  font-family:"Font Awesome 6 Free" !important;
  font-weight:900 !important;
  content:"\f00c" !important;
  display:flex !important;
  align-items:center !important;
  justify-content:center !important;
  font-size:10px !important;
  width:17px !important;
  height:17px !important;
  top:1px !important;
  left:0 !important;
  border-radius:5px !important;
}

/* Raw, unwrapped checkboxes (no .checkbox/label wrapper) — some
   DataTable bulk-select headers use these directly. */
table input[type="checkbox"]:not(.chk),
table input[type="radio"]{
  width:16px; height:16px;
  accent-color:var(--o-c1);
  cursor:pointer;
  vertical-align:middle;
}

/* ---- Tables / DataTables ---- */
.table > thead > tr > th{
  color:var(--o-text-low);
  font-size:10.5px;
  text-transform:uppercase;
  letter-spacing:.06em;
  font-weight:700;
  border-bottom:1px solid var(--o-border);
}
/* color found missing here while dark-mode-testing the Roles/
   Permissions grid: this instance's compiled Tailwind bundle
   (assets/builds/tailwind.css) hardcodes rgb(75,85,99) — a mid-grey
   tuned for light backgrounds — on the EXACT same selector chain
   (.table > tbody > tr > td), app-wide, not just this one screen.
   Fine as low-contrast-but-tolerable in light mode; low-contrast-to-
   unreadable on a dark card. Same specificity as the source rule, so
   !important is needed to guarantee this wins regardless of
   stylesheet load order — same reasoning as the other Tailwind-bundle
   overrides found this session (.fc-button-primary, .fc-day-other). */
.table > tbody > tr > td{
  color:var(--o-text-hi) !important;
  border-top:1px solid var(--o-border);
  font-size:13px;
  vertical-align:middle;
}
.table > tbody > tr:hover > td{background:color-mix(in srgb, var(--o-c1) 4%, transparent);}

/* ---- .table-bordered ----
   Bootstrap hardcodes a #ddd grey border on every cell edge here
   (verified: assets/plugins/bootstrap/css/bootstrap.css, .table-bordered
   rule) — the rule above only themes the top border via .table, so
   left/right/bottom edges on any .table-bordered instance stayed
   Bootstrap's stock grey, clashing with the theme everywhere else.
   Confirmed via repo grep this class is reused across 12 views
   (Roles/Permissions grid, Credit Notes, Payments, Email Templates,
   Reports > Expenses, Task view, Settings > Info, Customer Statement,
   Project PM view) — one fix here covers all of them. !important
   needed: selector chain is identical to Bootstrap's own
   (.table-bordered > thead > tr > th etc.), so specificity ties and
   load order alone would decide the winner — same reasoning already
   used for .dataTables_wrapper's border-color override below. */
.table-bordered,
.table-bordered > thead > tr > th,
.table-bordered > tbody > tr > th,
.table-bordered > tfoot > tr > th,
.table-bordered > thead > tr > td,
.table-bordered > tbody > tr > td,
.table-bordered > tfoot > tr > td{
  border-color:var(--o-border) !important;
}

.dataTables_wrapper .dataTables_filter input,
.dataTables_wrapper .dataTables_length select{
  border-radius:var(--o-radius-sm);
  border-color:var(--o-border-strong) !important;
}

/* ---- Pagination ----
   This install's DataTables integration renders Bootstrap's own markup
   (ul.pagination > li.paginate_button > a), not the plain-DataTables
   paginate_button-on-<a> structure — same structure theme_v1 already
   verified live. */
.dataTables_wrapper .dataTables_paginate ul.pagination{margin:0;}
.dataTables_wrapper .dataTables_paginate ul.pagination > li{margin-left:4px;}
.dataTables_wrapper .dataTables_paginate ul.pagination > li > a,
.dataTables_wrapper .dataTables_paginate ul.pagination > li > span{
  border-radius:9px !important;
  border-color:var(--o-border-strong);
  color:var(--o-text-mid);
}
.dataTables_wrapper .dataTables_paginate ul.pagination > li.active > a,
.dataTables_wrapper .dataTables_paginate ul.pagination > li.active > a:hover,
.dataTables_wrapper .dataTables_paginate ul.pagination > li.active > a:focus{
  background:linear-gradient(180deg,var(--o-c1-light),var(--o-c1)) !important;
  border-color:transparent !important;
  color:#fff !important;
}
.dataTables_wrapper .dataTables_paginate ul.pagination > li.disabled > a{
  color:var(--o-text-low);
  opacity:.6;
}
.dataTables_wrapper .dataTables_paginate ul.pagination > li:not(.active):not(.disabled) > a:hover{
  background:var(--o-surface-2);
  border-color:var(--o-border-strong);
}

/* ---- Badges / status labels ---- */
.label{border-radius:99px; font-weight:700; font-size:10.5px; padding:4px 10px;}
.label-info{background:color-mix(in srgb, var(--o-c1) 14%, transparent); color:var(--o-c1);}
.label-success{background:color-mix(in srgb, var(--o-success) 14%, transparent); color:var(--o-success);}
.label-warning{background:color-mix(in srgb, var(--o-c2) 20%, transparent); color:#8A5A00;}
.label-danger{background:color-mix(in srgb, var(--o-danger) 14%, transparent); color:var(--o-danger);}
.label-default{background:var(--o-surface-2); color:var(--o-text-mid);}
/* Same darkened-shade-for-light-contrast issue as .alert-warning above —
   #8A5A00 (needed for legible amber-on-near-white) inverts to
   low-contrast on a dark badge background; the raw --o-c2 reads better
   there instead. */
[data-theme="dark"] .label-warning{color:var(--o-c2);}

/* ---- Alerts ----
   The success/warning/danger text colors below (#1C8F5A/#8A5A00/
   #B23A45) are deliberately DARKENED shades of their semantic colors —
   needed for legible contrast against the alert's own near-white
   tinted background in light mode. That relationship inverts once the
   alert sits on a dark page: the same darkened shades read as
   low-contrast on a near-black tinted background, where the RAW
   semantic color (already vivid enough to work as button/status-dot
   colors elsewhere in both themes) is what's actually legible. Fixed
   via a dark-mode override further down rather than baking dark
   values in here, so the reasoning for each stays next to its own
   context. */
.alert{border-radius:var(--o-radius-sm); border-width:1px;}
.alert-info{background:color-mix(in srgb, var(--o-c1) 8%, transparent); border-color:color-mix(in srgb, var(--o-c1) 20%, transparent); color:var(--o-c1);}
.alert-success{background:color-mix(in srgb, var(--o-success) 8%, transparent); border-color:color-mix(in srgb, var(--o-success) 20%, transparent); color:#1C8F5A;}
.alert-warning{background:color-mix(in srgb, var(--o-c2) 12%, transparent); border-color:color-mix(in srgb, var(--o-c2) 25%, transparent); color:#8A5A00;}
.alert-danger{background:color-mix(in srgb, var(--o-danger) 8%, transparent); border-color:color-mix(in srgb, var(--o-danger) 20%, transparent); color:#B23A45;}
[data-theme="dark"] .alert-success{color:var(--o-success);}
[data-theme="dark"] .alert-warning{color:var(--o-c2);}
[data-theme="dark"] .alert-danger{color:var(--o-danger);}

/* ---- Modals ----
   Like .form-control/.dropdown-menu above, no background/color was
   set here before dark mode existed, so it silently inherited
   Bootstrap's hardcoded white modal background. */
.modal-content{
  background:var(--o-surface);
  color:var(--o-text-hi);
  border-radius:var(--o-radius-lg);
  border:none;
  box-shadow:var(--o-shadow-soft);
}
/* .modal-header specifically was missing background/color — found via
   a proactive scan of this instance's compiled Tailwind bundle for
   more of the same "hardcoded color on a real component class"
   pattern already caught for .fc-button-primary/.fc-day-other/table
   text: .modal-header{background-color:rgb(255,255,255)} and
   .modal-title{color:rgb(55,65,81)}, both unconditional. Since
   .modal-content (the parent) IS themed dark, this would have been an
   opaque white bar sitting inside an otherwise-dark modal — worse
   than the earlier gaps, since it's a visible internal seam rather
   than a whole surface being wrong. */
.modal-header{background:var(--o-surface); border-bottom:1px solid var(--o-border);}
.modal-title{color:var(--o-text-hi);}
.modal-footer{border-top:1px solid var(--o-border);}
/* .modal-body itself was ALSO never given a background — same class
   of gap as .panel-body, found live via a real bug report (the Task
   detail modal, /admin/tasks). Confirmed via source (assets/css/
   style.css): .task-modal-single .modal-body{background:#f8fafc} and
   .task-single-col-left{background:#fff} are both hardcoded, opaque,
   task-modal-specific — sitting on top of the already-correctly-dark
   .modal-content, exactly the same "child's opaque background covers
   the parent's" issue as .panel-body. transparent lets the dark
   .modal-content show through, same safe fix pattern. */
.modal-body{background:transparent;}
.task-modal-single .modal-body{background:transparent;}
.task-single-col-left{background:transparent;}

/* ---- Tabs ---- */
.nav-tabs{border-bottom:1px solid var(--o-border);}
.nav-tabs > li > a{
  border-radius:10px 10px 0 0;
  font-weight:600;
  color:var(--o-text-low);
}
.nav-tabs > li.active > a,
.nav-tabs > li.active > a:hover,
.nav-tabs > li.active > a:focus{
  color:var(--o-c1);
  border-color:var(--o-border) var(--o-border) transparent;
}

/* ---- Stacked left-rail nav (customer profile sidebar, GDPR settings) ----
   Verified live + against source (application/views/admin/clients/tabs.php):
   ul.nav-tabs.nav-stacked.customer-tabs > li[.active] > a[data-group] >
   i.menu-icon + text + span.badge.pull-right. Only two views in the whole
   app use .nav-stacked (customer profile + GDPR), so scoping to the class
   itself (not just .customer-tabs) covers both for free. Restyled from a
   flat list into the same card+pill treatment as the main app sidebar
   (.metis-menu) — higher specificity than the generic .nav-tabs rule
   above (3 classes vs 1), so no !important needed to win the cascade. */
.nav-tabs.nav-stacked{
  background:linear-gradient(160deg, var(--o-surface), var(--o-bg-elevated) 160%);
  border:1px solid var(--o-border);
  border-radius:var(--o-radius-lg);
  box-shadow:var(--o-shadow-card);
  padding:10px;
}
.nav-tabs.nav-stacked > li{margin-bottom:2px;}
.nav-tabs.nav-stacked > li > a{
  border-radius:12px;
  font-weight:600;
  font-size:13px;
  color:var(--o-text-mid);
  padding:10px 12px;
  display:flex;
  align-items:center;
}
/* margin-inline-end (not margin-right) — found live while verifying
   RTL: this link is display:flex with the icon <i> first in DOM order
   and no core rtl: utility on it (unlike the Dashboard KPI icons
   above, which get free RTL handling from Perfex's own template —
   this is purely this theme's own markup-adjacent styling, so it
   needed the fix itself). flex-direction:row visually reverses with
   the page's dir in RTL, so a hardcoded margin-right sat on the wrong
   side of the icon (toward the panel edge instead of toward the
   text) — collapsed the real icon-to-text gap to whatever residual
   margin core provided (4px) while opening an unwanted 10px gap on
   the edge side. A logical property fixes both directions at once. */
.nav-tabs.nav-stacked > li > a .menu-icon{width:16px; text-align:center; margin-inline-end:10px; opacity:.75; color:var(--o-text-mid);}
.nav-tabs.nav-stacked > li > a:hover{background:var(--o-surface-2); color:var(--o-text-hi);}
.nav-tabs.nav-stacked > li.active > a,
.nav-tabs.nav-stacked > li.active > a:hover,
.nav-tabs.nav-stacked > li.active > a:focus{
  background:linear-gradient(135deg, var(--o-c1-light), var(--o-c1));
  color:#fff;
  border-color:transparent;
}
.nav-tabs.nav-stacked > li.active > a .menu-icon{color:#fff; opacity:1;}
.nav-tabs.nav-stacked > li > a .badge{
  background:var(--o-surface-2);
  color:var(--o-text-mid);
  border-radius:99px;
  font-weight:700;
}
.nav-tabs.nav-stacked > li.active > a .badge{background:rgba(255,255,255,.25); color:#fff;}

/* ---- Segmented tabs (.nav-tabs-segmented) ----
   Confirmed live on the Lead profile modal (Profile/Proposals/Tasks/
   Attachments/Reminders/Notes/Activity Log) and via repo grep reused
   across 10 real screens: Contracts, Estimate Request, Expenses,
   Leads (formbuilder + profile), Projects tabs, Spam Filters, Staff
   member, Tickets. No core CSS defines this class at all (checked
   assets/css/style.css — zero hits) — it's entirely a COMPILED
   Tailwind rule (assets/builds/tailwind.css): grey track, active item
   gets white bg + rounded + shadow. That rule doesn't use !important,
   but its selector chain (.nav-tabs-segmented, .nav-tabs-segmented>
   li.active>a) has the SAME specificity as this override, so without
   !important it'd be a load-order coin flip — same defensive reasoning
   already used elsewhere in this file for genuine specificity ties
   (table-bordered, reports nav). This maps directly to a real
   component already in the approved mockup's own design system
   (ThemeComponents.html's .seg/.seg button.active — elevated track,
   even-more-elevated active pill + shadow, NOT a solid color fill)
   — matching that exact visual language here rather than inventing
   a new one. */
.nav-tabs-segmented{
  background:var(--o-bg-elevated) !important;
  border-radius:var(--o-radius-sm);
}
.nav-tabs-segmented > li > a{
  color:var(--o-text-mid);
  font-weight:600;
  border-radius:9px;
}
.nav-tabs-segmented > li.active > a,
.nav-tabs-segmented > li.active > a:hover,
.nav-tabs-segmented > li.active > a:focus{
  background:var(--o-surface) !important;
  color:var(--o-text-hi);
  box-shadow:var(--o-shadow-card);
}
.nav-tabs-segmented > li > a > .badge{
  background:var(--o-surface-2) !important;
  color:var(--o-text-mid);
}
.nav-tabs-segmented > li.active > a > .badge{background:var(--o-c1) !important; color:#fff;}

/* ---- Tailwind-utility stat pills ----
   Perfex renders these entirely with inline Tailwind utility classes
   (no semantic class name) — e.g. "7 Total Customers" on the Customers
   list, the per-status buttons on Invoices/Estimates quick-stats, the
   sidebar profile-chip toggle. Initially left alone (Phase 1) as a
   one-off with no safe selector; a repo-wide grep now shows the exact
   5-class combo below is the deliberate, reused signature for this
   component across at least 12 views (clients, contracts, estimates,
   expenses, invoices, leads, projects, staff, tasks, tickets, the
   sidebar profile toggle) — specific enough to target safely rather
   than matching any single bare utility like .tw-bg-white alone.
   5-class compound selector already outweighs any single-property
   Tailwind utility's specificity, so no !important needed. */
.tw-bg-white.tw-border.tw-border-solid.tw-shadow-sm.tw-rounded-lg{
  background:var(--o-surface);
  border-color:var(--o-border);
  border-radius:var(--o-radius-sm);
  box-shadow:var(--o-shadow-card);
}
.tw-bg-white.tw-border.tw-border-solid.tw-shadow-sm.tw-rounded-lg:hover{
  border-color:var(--o-border-strong);
}

/* ---- Reports left-nav (Sales report picker) ----
   Verified against source (application/views/admin/reports/sales.php +
   includes/sales_js.php): ul.reports > li > a, active state toggled by
   plain jQuery ($(e).attr('data-active', true)) — not Alpine, so a
   normal CSS attribute selector works. Only this one screen uses
   ul.reports (checked via grep), but it's a real, frequently-used
   screen with ~10 report links, so still worth the dedicated rule.
   Matches the same "pill on active" language as .nav-tabs.nav-stacked
   above, for visual consistency between the two sidebar-style navs.
   !important needed here: this competes directly with Tailwind's own
   compiled data-[active=true]:tw-bg-white / :tw-shadow-sm utilities on
   the exact same attribute selector — equal specificity, and
   Tailwind's stylesheet loads after theme_orbit's (priority-5
   app_admin_head hook fires early in <head>), so it would win the
   cascade tie without it. */
.reports a[data-active="true"]{
  background:linear-gradient(135deg, var(--o-c1-light), var(--o-c1)) !important;
  border-color:transparent !important;
  color:#fff !important;
  box-shadow:0 8px 18px -8px color-mix(in srgb, var(--o-c1) 65%, transparent);
}
.reports a[data-active="true"] svg{color:#fff !important;}
.reports a{border-radius:var(--o-radius-sm) !important;}

/* ---- Dropdown menus (generic, outside header) ----
   Bootstrap's own .dropdown-menu > li > a hardcodes #333 text / #f5f5f5
   hover background (verified: assets/plugins/bootstrap/css/bootstrap.css)
   — fine as an invisible no-op in light mode, but low-contrast on a
   dark surface once dark mode exists, so themed explicitly here too. */
.dropdown-menu{
  background:var(--o-surface);
  color:var(--o-text-hi);
  border:1px solid var(--o-border-strong);
  border-radius:var(--o-radius-md);
  box-shadow:var(--o-shadow-soft);
}
.dropdown-menu > li > a{color:var(--o-text-mid);}
.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus{color:var(--o-text-hi); background:var(--o-surface-2);}

/* ---- On/off switch (.onoffswitch — real toggle used across 5+ views:
   Attachments, Contact modal, Knowledge Base groups, Project
   activity/files "visible to customer" toggles) ----
   Found via the same proactive Tailwind-bundle scan. Off-state track/
   border was a hardcoded light grey (rgb(229,231,235)) — same
   invisible-in-light/glaring-in-dark class of bug as everything else
   in this pass. On-state was a hardcoded generic Tailwind blue
   (rgb(59,130,246)), unrelated to this theme's actual brand color in
   EITHER mode — re-themed to var(--o-c1) for consistency, not just a
   dark-mode fix. Knob stays white in both themes (deliberate — a
   white knob against a colored/dark track is the standard, always-
   legible convention for this control, not something dark mode
   should change). */
.onoffswitch-label, .onoffswitch-label::before{border-color:var(--o-border-strong);}
.onoffswitch-label{background:var(--o-surface-2);}
.onoffswitch-checkbox:checked + .onoffswitch-label{background:var(--o-c1);}
.onoffswitch-checkbox:checked + .onoffswitch-label,
.onoffswitch-checkbox:checked + .onoffswitch-label::before{border-color:var(--o-c1);}

/* Bare .badge (small numeric counters — e.g. reminders/announcements
   count on Dashboard widgets) — found the same way; themed to this
   file's existing "neutral badge" language (matches .label-default). */
.badge{background:var(--o-surface-2); color:var(--o-text-mid);}

/* ---- Mono numerics (invoice #, amounts, dates) ---- */
.mono, .text-mono{font-family:var(--o-font-display); font-weight:600;}

/* ---- Menu Setup drag-tree (Setup > Menu Editor) ----
   Previously flagged as a known, deliberately-unstyled gap (couldn't
   verify live at the time) — closed out now that live browser access
   exists. Real classes verified via live DOM + the actual shipped
   source (assets/css/style.css, ~line 2761-2845): this is the
   "Nestable" jQuery plugin's own default styling — .dd3-content is
   the visible chip for each menu row, .dd3-handle the small drag-grip
   icon on its left edge. Confirmed live: hardcoded near-white
   (#fbfbfb/#fff) chip background with dark text — a glaring white box
   on this theme's dark sidebar-adjacent settings page. .dd3-content's
   own background rule uses !important (as does .sub-items .dd3-content
   for nested rows), so this needs !important too. .dd3-handle:before's
   icon glyph is hardcoded white — left alone since it needs to stay
   legible against .dd3-handle's own background in both themes, and a
   light neutral handle background (rather than matching the dark
   surface) keeps enough contrast for that white glyph without having
   to also recolor the icon. */
.dd-handle{
  background:var(--o-surface-2);
  border-color:var(--o-border-strong);
  color:var(--o-text-hi);
}
.dd-handle:hover{background:var(--o-surface); color:var(--o-c1);}
.dd3-content, .sub-items .dd3-content{
  background:var(--o-surface-2) !important;
  border-color:var(--o-border-strong);
  color:var(--o-text-hi);
}
.dd-placeholder, .dd-empty{
  background:color-mix(in srgb, var(--o-c1) 8%, var(--o-bg-base));
  border-color:var(--o-border-strong);
}

/* ---- Staff/user avatars ----
   Perfex always renders a real <img> here (photo, or a placeholder JPG
   if none is set — verified against source, application/helpers/
   staff_helper.php: staff_profile_image()), never initials-only like
   the mockup's .avatar component. Circle shape/sizing already comes
   from core (.staff-profile-image-small/-xs/-thumb/-xs-image, each
   with their own width/height/border-radius:50% — untouched here, so
   this can't break any layout that depends on those exact pixel
   sizes). Adding only a themed ring + soft shadow around the existing
   image — the closest equivalent of the mockup's avatar treatment
   without replacing real photos with a different rendering approach,
   which would be a markup/logic change, not a restyle. */
.staff-profile-image,
.staff-profile-image-small,
.staff-profile-image-xs,
.staff-profile-image-thumb,
.staff-profile-xs-image,
.client-profile-image-thumb{
  border:2px solid var(--o-surface);
  box-shadow:0 0 0 1px var(--o-border), var(--o-shadow-card);
}

/* ---- Kanban boards ----
   #kan-ban is one shared partial reused verbatim across 6 different
   boards (verified via repo grep): Tasks, Leads pipeline, Estimates
   pipeline, Proposals pipeline, Project Milestones, Knowledge Base
   articles — one fix here covers all of them. Column wrapper is
   already .panel_s (covered by the earlier .panel_s rule); the column
   HEADER sets its status color via inline style (border-color from
   PHP, e.g. style="background:<?=$status['color']?>") which always
   wins over any class-based rule regardless of specificity, so it's
   correctly left untouched here — don't add a .panel-heading override
   that would fight it. Individual cards are NOT wrapped in .panel_s
   (verified against source: application/views/admin/tasks/
   _kan_ban_card.php — just <li class="task"><div class="panel-body"
   style="border-top:2px solid <priority-color>">), so they need their
   own card treatment. Priority-color top border (inline, per-task) is
   also left untouched for the same inline-style-always-wins reason. */
/* Real, pre-existing bug (not caused by this theme, but genuinely
   broken without this fix — reported live: /admin/tasks rendered as
   an almost-empty page, no visible board). Found via computed style:
   #kan-ban's columns (.kan-ban-col) are float:left with real content/
   height, but #kan-ban itself collapsed to height:0 — a classic
   floated-children-collapse-their-parent issue. Core's OWN CSS has
   the fix for this (.kb-kan-ban#kan-ban{overflow:auto} — establishes
   a new block formatting context, which correctly contains floated
   children's height), but the live-rendered #kan-ban element in this
   install has an EMPTY class attribute — it never carries the
   `kb-kan-ban` class core's selector requires, so that rule never
   matches and the containment never kicks in. This is a markup/CSS
   mismatch in Perfex core itself (verified: the class name is simply
   absent from the live DOM), unrelated to anything this theme
   changed — fixed here with a plain #kan-ban{overflow:auto} rather
   than editing core markup to add the missing class. Verified live:
   #kan-ban went from height:0 to height:841px (matching its real
   column content) after this exact change. */
#kan-ban{overflow:auto;}
.kan-ban-content{background:var(--o-bg-base);}
/* Same RTL border-color gap as the sidebar above: Kanban's column
   wrapper uses the generic ".border-right" utility class (verified:
   tasks/kan_ban.php renders <div class="border-right panel_s">), and
   core's [dir="rtl"] .border-right rule swaps it to a hardcoded grey
   (#e2e8f0) border-left instead of any theme value. */
[dir="rtl"] .border-right{border-left-color:var(--o-border);}
#kan-ban .panel-body{
  background:var(--o-surface);
  border:1px solid var(--o-border);
  border-radius:var(--o-radius-sm);
  box-shadow:var(--o-shadow-card);
  transition:transform .12s ease, box-shadow .15s ease;
}
#kan-ban .panel-body:hover{
  transform:translateY(-2px);
  box-shadow:var(--o-shadow-soft);
}

/* Found while dark-mode-testing the Kanban board: core has its own
   semantic highlight for "your task" / "your lead" (light blue) and
   "overdue" (light red) cards — verified in assets/css/style.css:
   li.task.current-user-task .panel-body, li.lead-kan-ban.current-user-
   lead .panel-body { background:#eff6ff !important; border:1px solid
   #dbeafe !important; } and li.task.overdue-task .panel-body {
   background:#fef2f2 !important; ... }. Those hardcoded pale colors
   were completely invisible against a dark board — the highlight
   effectively vanished in dark mode, and even in light mode they were
   disconnected from this theme's own palette. Re-themed with the same
   MEANING (info tint = yours, danger tint = overdue) using this
   theme's own tokens instead, matching the same tinted-background
   pattern already used for alerts/badges. Needs !important: core's
   own rule already uses it, so a non-!important override would lose
   regardless of specificity. */
li.task.current-user-task .panel-body,
li.lead-kan-ban.current-user-lead .panel-body{
  background:color-mix(in srgb, var(--o-c1) 10%, var(--o-surface)) !important;
  border:1px solid color-mix(in srgb, var(--o-c1) 25%, transparent) !important;
}
li.task.overdue-task .panel-body{
  background:color-mix(in srgb, var(--o-danger) 10%, var(--o-surface)) !important;
  border:1px solid color-mix(in srgb, var(--o-danger) 25%, transparent) !important;
}

/* ---- Gantt chart (Project > Gantt tab) ----
   Confirmed live (Project #21 > Gantt): renders as Frappe Gantt v3.2.0
   (window.Gantt present; script src assets/plugins/frappe/frappe-gantt-
   es2015.js?v=3.2.0), an SVG-based library. Selectors and their exact
   default values below are copied from the ACTUAL shipped source
   (assets/plugins/frappe/frappe-gantt.css) — not guessed from a
   screenshot — so every property here is a deliberate override of a
   real, documented rule, not a blind addition. SVG presentation
   properties (fill/stroke) accept CSS custom properties the same as
   any other property when set via an external stylesheet like this
   one (only inline SVG attributes can't use var()), so the theme
   tokens apply directly. Bars/progress recolored to the two brand
   colors; grid/ticks/text tied to the theme's neutral tokens; today
   marker tinted with c2 instead of the library's hardcoded yellow;
   popup tooltip gets the theme's card treatment (radius/shadow) to
   match every other popover in the app. */
.gantt .grid-header{fill:var(--o-surface); stroke:var(--o-border);}
/* .grid-row itself (odd rows) was missed originally — only the even
   rule was overridden, leaving Frappe Gantt's own hardcoded
   .grid-row{fill:#ffffff} in place for odd rows. Invisible-in-light-
   mode bug, same class as the form-control/modal/dropdown gaps found
   earlier: a glaring white stripe once dark mode existed to expose it. */
.gantt .grid-row{fill:var(--o-surface);}
.gantt .grid-row:nth-child(even){fill:var(--o-bg-elevated);}
.gantt .row-line{stroke:var(--o-border);}
.gantt .tick{stroke:var(--o-border);}
.gantt .today-highlight{fill:var(--o-c2); opacity:.12;}
.gantt .arrow{stroke:var(--o-text-low);}
.gantt .bar{fill:var(--o-surface-2); stroke:var(--o-border-strong);}
.gantt .bar-progress{fill:var(--o-c1);}
.gantt .bar-invalid{stroke:var(--o-text-low);}
.gantt .bar-invalid ~ .bar-label{fill:var(--o-text-mid);}
.gantt .bar-label{fill:#fff;}
.gantt .bar-label.big{fill:var(--o-text-hi);}
.gantt .bar-wrapper:hover .bar,
.gantt .bar-wrapper.active .bar{fill:var(--o-c1-light);}
.gantt .bar-wrapper:hover .bar-progress,
.gantt .bar-wrapper.active .bar-progress{fill:var(--o-c1-dark);}
.gantt .upper-text,
.gantt .lower-text{fill:var(--o-text-mid); font-family:var(--o-font-body);}
.gantt-container .popup-wrapper{
  background:var(--o-text-hi);
  border-radius:var(--o-radius-sm);
  box-shadow:var(--o-shadow-soft);
}
.gantt-container .popup-wrapper .title{border-bottom-color:var(--o-c1);}

/* ---- Calendar (Utilities > Calendar) ----
   Confirmed live (admin/utilities/calendar): renders as FullCalendar
   v3.2.0-bundled main.min.js. Unlike Frappe Gantt, this library ships
   its own official CSS custom-property theming API (verified against
   the actual shipped source, assets/plugins/fullcalendar/lib/main.css
   — every visual rule reads its color via var(--fc-*, <default>), e.g.
   ".fc-theme-standard td{border:1px solid var(--fc-border-color,#ddd)}").
   Setting these variables is the library's own intended integration
   point, not a workaround — no selector-matching or specificity fight
   needed, so no !important anywhere in this block. Defaults being
   replaced (confirmed via grep across main.css): border #ddd, button
   bg/border #2C3E50, event bg/border #3788d8 (Perfex's own stock
   blue), today-highlight a hardcoded yellow rgba(255,220,40,.15) —
   swapped for c2 to match the same today-marker treatment already
   applied to the Gantt chart above, for consistency between the two
   calendar-like views. */
.fc{
  --fc-border-color:var(--o-border);
  --fc-page-bg-color:var(--o-surface);
  --fc-neutral-bg-color:var(--o-bg-elevated);
  --fc-neutral-text-color:var(--o-text-mid);
  --fc-button-bg-color:var(--o-c1);
  --fc-button-border-color:var(--o-c1);
  --fc-button-hover-bg-color:var(--o-c1-dark);
  --fc-button-hover-border-color:var(--o-c1-dark);
  --fc-button-active-bg-color:var(--o-c1-dark);
  --fc-button-active-border-color:var(--o-c1-dark);
  --fc-event-bg-color:var(--o-c1);
  --fc-event-border-color:var(--o-c1-dark);
  --fc-event-text-color:#fff;
  --fc-today-bg-color:color-mix(in srgb, var(--o-c2) 14%, transparent);
  --fc-list-event-hover-bg-color:var(--o-bg-elevated);
  --fc-highlight-color:color-mix(in srgb, var(--o-c1) 12%, transparent);
}
.fc .fc-toolbar-title{font-family:var(--o-font-display); color:var(--o-text-hi);}
/* border-radius isn't one of the library's themeable variables (checked
   the var list above — it's not there), so this one property has to be
   a plain override instead. Same selector chain as the library's own
   rule (.fc .fc-button{border-radius:.25em}) — equal specificity, and
   this page's plugin CSS may load after this theme's early priority-5
   hook, so !important is the safe choice here, unlike the color/bg
   properties above which all go through the official var() API and
   need none. */
.fc .fc-button{border-radius:var(--o-radius-sm) !important; font-weight:600;}

/* .fc-button-primary specifically needs its own explicit override,
   discovered live (not guessed): this Perfex instance's own COMPILED
   Tailwind bundle (assets/builds/tailwind.css) contains a deliberate,
   hardcoded dark-slate !important rule targeting ".fc-button-primary"
   directly (background/border/color, base + hover/active/focus states
   — confirmed via live CSSOM inspection of the actual rule text) that
   ignores the --fc-button-bg-color variable entirely. This predates
   Theme Orbit — it's baked into core's own build, not caused by this
   theme. Since it's !important, only a strictly higher-specificity
   !important rule reliably wins regardless of stylesheet load order
   (".fc .fc-button-primary" = 2 classes beats the stock rule's 1). */
.fc .fc-button-primary{
  background-color:var(--o-c1) !important;
  border-color:var(--o-c1) !important;
  color:#fff !important;
}
.fc .fc-button-primary.fc-button-active,
.fc .fc-button-primary:active,
.fc .fc-button-primary:focus,
.fc .fc-button-primary:hover{
  background-color:var(--o-c1-dark) !important;
  border-color:var(--o-c1-dark) !important;
  color:#fff !important;
}
.fc-theme-standard .fc-popover{border-radius:var(--o-radius-md); box-shadow:var(--o-shadow-soft); overflow:hidden;}
.fc-theme-standard .fc-popover-header{background:var(--o-bg-elevated);}
/* .fc-day-other (the greyed padding days at the start/end of a month
   grid) has the SAME pre-baked-into-this-instance's-Tailwind-bundle
   issue as .fc-button-primary above — found live via CSSOM inspection:
   a hardcoded rgb(249,250,251) in assets/builds/tailwind.css that
   ignores the --fc-* variable API entirely. No !important on the
   source rule this time, but overridden defensively with !important
   anyway for the same load-order-uncertainty reason as the button fix. */
.fc .fc-day-other{background-color:var(--o-bg-base) !important;}

/* ---- Perfex Dashboard: widget move/delete controls ----
   Real classes verified live for theme_v1: delete = "x" is
   .perfexdashboard-widget-removable, whose ::before uses the legacy
   FontAwesome v4 family alias — force it onto the real loaded family,
   "Font Awesome 6 Free" solid (weight 900). Move handle = .widget-dragger. */
.perfexdashboard-widget-removable,
.perfexdashboard-widget-changeable,
.widget-dragger{
  width:26px; height:26px;
  display:flex; align-items:center; justify-content:center;
  background:var(--o-surface);
  border:1px solid var(--o-border);
  border-radius:50%;
  box-shadow:var(--o-shadow-card);
  color:var(--o-text-low);
  transition:transform .12s ease, color .12s ease, border-color .12s ease;
}
.perfexdashboard-widget-removable:before,
.perfexdashboard-widget-changeable:before,
.widget-dragger:before{
  font-size:11px;
}
.perfexdashboard-widget-removable:before{
  font-family:"Font Awesome 6 Free" !important;
  font-weight:900 !important;
}
.perfexdashboard-widget-removable:hover{
  color:#fff;
  background:linear-gradient(180deg,#FF8FA3,var(--o-danger));
  border-color:transparent;
  transform:scale(1.08);
}
.perfexdashboard-widget-changeable:hover,
.widget-dragger:hover{
  color:#fff;
  background:linear-gradient(180deg,var(--o-c1-light),var(--o-c1));
  border-color:transparent;
  transform:scale(1.08);
}
.perfexdashboard-widget-changeable:active,
.perfexdashboard-widget-removable:active,
.widget-dragger:active{
  cursor:grabbing;
}

/* ---- Responsive ----
   Perfex's own mobile sidebar mechanism (verified against source,
   assets/css/style.css): .sidebar is position:absolute (not fixed),
   and body.page-small / body.show-sidebar (JS-toggled) slide it via
   margin-left on #menu / #wrapper — there's no max-width media query
   driving it directly, the breakpoint is JS-determined. An earlier
   version here forced #menu.sidebar to position:fixed at 1024px,
   fighting that margin-based slide and quite possibly breaking the
   mobile drawer — removed. 768px is core's own dominant breakpoint
   (confirmed via grep: assets/css/style.css uses it ~30 times, 1024px
   almost nowhere), so new/changed rules below key off that, not an
   invented number. Only styling adjustments for elements THIS theme
   added or changed — never touches position/margin/JS-driven classes,
   so it can't interfere with core's own drawer logic. */
@media (max-width:768px){
  .panel_s .panel-body{padding:16px 16px;}
  .top_stats_wrapper{padding:14px 16px !important;}
  .nav-tabs.nav-stacked{padding:8px;}
  .nav-tabs.nav-stacked > li > a{padding:9px 10px; font-size:12.5px;}
}
