/*
 * SaverBro Dark POS
 * A presentation-only layer loaded after the legacy application styles.
 * It deliberately retains existing DOM hooks so POS flows and modules stay unchanged.
 */
:root {
  color-scheme: dark;
  --sb-bg: #080d17;
  --sb-surface: #101827;
  --sb-surface-raised: #162235;
  --sb-surface-hover: #1d2b40;
  --sb-border: #25344b;
  --sb-border-strong: #354966;
  --sb-text: #edf4ff;
  --sb-muted: #97a9c1;
  --sb-faint: #687b96;
  --sb-accent: #38bdf8;
  --sb-accent-strong: #0284c7;
  --sb-success: #34d399;
  --sb-warning: #fbbf24;
  --sb-danger: #fb7185;
  --theme-700: #38bdf8;
  --theme-800: #0f3a5a;
  --theme-900: #0a1c30;
}

html,
body,
body .thetop,
body .thetop > main {
  background: var(--sb-bg) !important;
  color: var(--sb-text);
}

body {
  font-feature-settings: "ss01" 1, "cv02" 1;
}

body:not(.lockscreen) #scrollable-container {
  background:
    radial-gradient(circle at 80% -15%, rgba(14, 116, 144, .16), transparent 29rem),
    var(--sb-bg);
}

/* Application shell */
.theme-header-bg,
body .theme-header-bg {
  background: linear-gradient(110deg, #080e19 0%, #0d1d31 52%, #080e19 100%) !important;
}

.side-bar {
  background: #0c1422 !important;
  border-right: 1px solid var(--sb-border) !important;
  box-shadow: 16px 0 34px rgba(0, 0, 0, .15);
}

.side-bar > a:first-child {
  min-height: 4.25rem !important;
  background: linear-gradient(135deg, #0f3858, #0b1d32) !important;
  border-color: rgba(56, 189, 248, .22) !important;
}

.side-bar-heading {
  letter-spacing: .02em;
  font-weight: 700 !important;
}

.saverpos-logo {
  display: block;
  object-fit: contain;
  background: transparent;
}

.saverpos-logo--sidebar {
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
  border-radius: 9px;
  padding: 3px;
}

.saverpos-logo--pos {
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  border-radius: 7px;
  padding: 1px;
}

.saverpos-logo--rail {
  background: #fff;
  border-radius: 50%;
  padding: 0;
  box-shadow: 0 1px 3px rgba(0,0,0,.2);
}

.saverpos-logo--pos + span {
  color: var(--sb-text) !important;
}

.right-col > .row:first-child img[alt="SAVERPOS logo"] {
  border-radius: 9px;
  padding: 3px;
}

.side-bar > div {
  border-color: var(--sb-border) !important;
}

.side-bar #sidebar-search > div,
#sidebar-search {
  color: var(--sb-text) !important;
}

.side-bar input#sidebar-search {
  background: transparent !important;
}

.side-bar input#sidebar-search::placeholder {
  color: var(--sb-faint) !important;
}

.side-bar .tw-bg-gray-100 {
  background: #121e2e !important;
  border-color: var(--sb-border) !important;
}

/* The 1px rule down each open submenu shares .tw-bg-gray-100 with the search
   field, so it inherited that #121e2e surface fill - 1.06:1 against the
   #101827 sidebar, i.e. not visible at all. A hairline needs to read as an
   edge, not a surface, so it takes the border token instead (1.94:1). The id
   outranks the rule above; the light sheet has its own override and is
   unaffected. */
#side-bar .chiled > .tw-bg-gray-100 {
  background: var(--sb-border-strong) !important;
}

#side-bar,
#side-bar .treeview-menu {
  background: transparent !important;
}

#side-bar li > a,
#side-bar .treeview-menu > li > a {
  color: var(--sb-muted) !important;
  border-radius: 9px;
  margin: 2px 9px;
  transition: background .16s ease, color .16s ease, transform .16s ease;
}

#side-bar li > a:hover,
#side-bar li.active > a,
#side-bar a.theme-sidebar-active {
  background: rgba(56, 189, 248, .11) !important;
  color: #e8f8ff !important;
  transform: translateX(2px);
}

/* Sub-menu items do get an active class, but the only styling behind it is
   color: var(--theme-700), which in this dark palette lands on practically the
   same tone as the inactive links - so the page you are on was impossible to
   pick out. Mirror the parent item's active treatment. */
#side-bar a.theme-sidebar-child-active {
  color: #e8f8ff !important;
  font-weight: 600;
  background: rgba(56, 189, 248, 0.11);
  border-radius: 6px;
}

#side-bar li > a:hover i,
#side-bar li > a:hover svg,
#side-bar li.active > a i,
#side-bar li.active > a svg,
#side-bar a.theme-sidebar-active i,
#side-bar a.theme-sidebar-active svg {
  color: var(--sb-accent) !important;
}

#side-bar .header,
#sidebar-no-results {
  color: var(--sb-faint) !important;
  background: transparent !important;
}

/* Sidebar workspace status */
.sb-sidebar-status {
  margin: .75rem;
  padding: .85rem;
  border: 1px solid rgba(56, 189, 248, .16);
  border-radius: .85rem;
  background: linear-gradient(135deg, rgba(20, 58, 88, .55), rgba(12, 24, 39, .92));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .035);
}

.sb-sidebar-status__brand {
  display: flex;
  align-items: center;
  gap: .65rem;
}

.sb-sidebar-status__logo {
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  padding: 2px;
  border-radius: 8px;
}

.sb-sidebar-status__name,
.sb-sidebar-status__business,
.sb-sidebar-status__meta {
  margin: 0;
}

.sb-sidebar-status__name {
  color: #effbff;
  font-size: .77rem;
  font-weight: 750;
  letter-spacing: .045em;
  line-height: 1.2;
}

.sb-sidebar-status__business {
  overflow: hidden;
  color: var(--sb-faint);
  font-size: .68rem;
  line-height: 1.45;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sb-sidebar-status__meta {
  display: flex;
  align-items: center;
  gap: .35rem;
  margin-top: .7rem;
  padding-top: .65rem;
  border-top: 1px solid rgba(148, 163, 184, .14);
  color: #9cb0c3;
  font-size: .67rem;
  font-weight: 600;
}

.sb-sidebar-status__dot {
  width: .42rem;
  height: .42rem;
  border-radius: 999px;
  background: #34d399;
  box-shadow: 0 0 0 3px rgba(52, 211, 153, .12);
}

.main-header,
.main-header .navbar,
.thetop > main > .no-print.theme-header-bg {
  border-color: rgba(56, 189, 248, .18) !important;
  box-shadow: 0 6px 22px rgba(0, 0, 0, .16);
}

/* Command-center header: styles existing controls without changing their behavior. */
.sb-command-header {
  position: relative;
  z-index: 10;
}

.sb-command-header::after {
  position: absolute;
  right: 1.25rem;
  bottom: -1px;
  left: 1.25rem;
  height: 1px;
  content: "";
  background: linear-gradient(90deg, transparent, rgba(56, 189, 248, .34), transparent);
  opacity: .7;
  pointer-events: none;
}

.sb-command-header__navigation > button,
.sb-command-header__actions > button,
.sb-command-header__actions > a,
.sb-command-header__actions > details > summary {
  box-shadow: 0 7px 18px rgba(0, 0, 0, .12);
}

.sb-command-header__primary-action {
  border-color: rgba(56, 189, 248, .44) !important;
  background: linear-gradient(135deg, rgba(14, 116, 144, .7), rgba(30, 64, 175, .72)) !important;
}

.sb-command-header__date {
  color: #b9e7ff !important;
  letter-spacing: .025em;
}

.sb-command-header button:focus-visible,
.sb-command-header a:focus-visible,
.sb-command-header summary:focus-visible {
  outline: 2px solid #38bdf8;
  outline-offset: 3px;
}

.theme-btn-bg,
.theme-logo-bg {
  background: rgba(56, 189, 248, .1) !important;
}

.theme-btn-bg:hover,
.theme-btn-bg:focus {
  background: rgba(56, 189, 248, .2) !important;
}

/* The account menu is rendered by the Tailwind dropdown partial, so keep it
   on the same dark surface as the rest of the SaverPOS shell. */
.sb-account-menu {
  z-index: 1050;
}

.sb-account-menu > summary {
  list-style: none;
}

.sb-account-menu > summary::-webkit-details-marker {
  display: none;
}

.sb-account-menu[open] > summary {
  box-shadow: 0 0 0 2px rgba(56, 189, 248, .32), 0 8px 24px rgba(0, 0, 0, .18) !important;
}

.sb-account-menu__panel {
  width: min(18rem, calc(100vw - 2rem)) !important;
  margin-top: .65rem !important;
  padding: .55rem !important;
  overflow: hidden;
  background: linear-gradient(155deg, #162a40 0%, #0d192a 100%) !important;
  border: 1px solid rgba(125, 211, 252, .38) !important;
  border-radius: 1rem !important;
  box-shadow: 0 20px 50px rgba(0, 0, 0, .42), 0 0 0 1px rgba(8, 21, 37, .8) !important;
  color: var(--sb-text) !important;
}

.sb-account-menu__meta {
  min-height: 4.15rem;
  margin-bottom: .35rem;
  padding: .75rem .7rem .8rem !important;
  border-bottom: 1px solid rgba(147, 169, 193, .2);
}

.sb-account-menu__eyebrow {
  margin: 0 0 .25rem;
  color: var(--sb-muted) !important;
  font-size: .72rem !important;
  letter-spacing: .02em;
}

.sb-account-menu__name {
  margin: 0;
  color: var(--sb-text) !important;
  font-size: .95rem !important;
}

.sb-account-menu__meta > svg,
.sb-account-menu__profile-icon {
  color: #a8d8f3 !important;
}

.sb-account-menu .sb-account-menu__item {
  min-height: 2.75rem;
  color: #d9e9f8 !important;
  border: 1px solid transparent;
  text-decoration: none !important;
}

.sb-account-menu .sb-account-menu__item:hover,
.sb-account-menu .sb-account-menu__item:focus-visible {
  background: rgba(56, 189, 248, .14) !important;
  border-color: rgba(56, 189, 248, .25);
  color: #f5fbff !important;
  outline: none;
}

.sb-account-menu__icon {
  flex: 0 0 auto;
  color: #8edbff !important;
}

.sb-account-menu__item--danger:hover,
.sb-account-menu__item--danger:focus-visible {
  background: rgba(251, 113, 133, .12) !important;
  border-color: rgba(251, 113, 133, .24);
}

.sb-account-menu__item--danger:hover .sb-account-menu__icon,
.sb-account-menu__item--danger:focus-visible .sb-account-menu__icon {
  color: #fda4af !important;
}

/* Surfaces, text and data density */
.content-wrapper,
.content,
.content-header,
.wrapper,
.bg-white,
.tw-bg-white {
  color: var(--sb-text);
}

.box,
.info-box,
.nav-tabs-custom,
.small-box,
.modal-content,
.popover,
.dropdown-menu,
.select2-dropdown,
.tw-dw-menu,
.tw-dw-dropdown-content {
  background: var(--sb-surface) !important;
  color: var(--sb-text) !important;
  border: 1px solid var(--sb-border) !important;
  box-shadow: 0 18px 45px rgba(0, 0, 0, .28) !important;
}

.box,
.info-box,
.nav-tabs-custom,
.small-box {
  border-radius: 14px !important;
}

/* Legacy utility classes are still used by Dashboard widgets and plugins.
   Keep those internal surfaces on the same visual system as the newer cards. */
.content .tw-bg-gray-50,
.content .tw-bg-gray-100,
.content .tw-bg-gray-200,
.content .tw-bg-slate-50,
.content .tw-bg-slate-100,
.saverbro-dashboard ~ .tw-bg-gray-50,
.saverbro-dashboard ~ .tw-bg-gray-100,
.saverbro-dashboard ~ .tw-bg-slate-50,
.saverbro-dashboard ~ .tw-bg-slate-100,
.saverbro-dashboard ~ * .tw-bg-gray-50,
.saverbro-dashboard ~ * .tw-bg-gray-100,
.saverbro-dashboard ~ * .tw-bg-slate-50,
.saverbro-dashboard ~ * .tw-bg-slate-100,
.saverbro-dashboard ~ * .tw-bg-white,
#scrollable-container .tw-bg-gray-50,
#scrollable-container .tw-bg-gray-100,
#scrollable-container .tw-bg-gray-200,
#scrollable-container .tw-bg-slate-50,
#scrollable-container .tw-bg-slate-100,
#scrollable-container .tw-bg-white,
.bg-gray-light,
.well,
.panel-default,
.panel-default > .panel-heading,
.list-group-item {
  background: var(--sb-surface) !important;
  color: var(--sb-text) !important;
  border-color: var(--sb-border) !important;
}

.content .tw-bg-gray-50,
.saverbro-dashboard ~ .tw-bg-gray-50,
.saverbro-dashboard ~ * .tw-bg-gray-50,
#scrollable-container .tw-bg-gray-50 {
  background: #0d1726 !important;
}

.content .tw-bg-gray-200,
.content .tw-bg-slate-100,
.saverbro-dashboard ~ .tw-bg-gray-100,
.saverbro-dashboard ~ .tw-bg-slate-100,
.saverbro-dashboard ~ * .tw-bg-gray-100,
.saverbro-dashboard ~ * .tw-bg-slate-100,
#scrollable-container .tw-bg-gray-100,
#scrollable-container .tw-bg-gray-200,
#scrollable-container .tw-bg-slate-100 {
  background: #111d2e !important;
}

.breadcrumb {
  background: rgba(16, 24, 39, .72) !important;
  color: var(--sb-muted) !important;
  border: 1px solid var(--sb-border);
}

.breadcrumb > li + li::before {
  color: var(--sb-faint) !important;
}

.alert-info,
.callout.callout-info {
  background: rgba(14, 116, 144, .2) !important;
  border: 1px solid rgba(56, 189, 248, .38) !important;
  color: #d8f3ff !important;
}

.alert-warning,
.callout.callout-warning {
  background: rgba(146, 94, 8, .2) !important;
  border: 1px solid rgba(251, 191, 36, .38) !important;
  color: #fef3c7 !important;
}

.alert-danger,
.callout.callout-danger {
  background: rgba(159, 18, 57, .2) !important;
  border: 1px solid rgba(251, 113, 133, .4) !important;
  color: #ffe4e6 !important;
}

/* Dashboard charts inherit white utility surfaces and a white Highcharts
   canvas. Keep the graph readable without changing its data. */
.sb-dashboard-chart-card {
  background: var(--sb-surface) !important;
  border-color: var(--sb-border) !important;
  box-shadow: 0 14px 32px rgba(0, 0, 0, .2) !important;
}

.sb-dashboard-chart-frame,
.sb-dashboard-chart-frame > div,
.sb-dashboard-chart-frame canvas,
.sb-dashboard-chart-frame svg,
.sb-dashboard-chart-frame .highcharts-container {
  background: transparent !important;
}

.sb-dashboard-chart-frame {
  background: #0d1726 !important;
  border-color: var(--sb-border) !important;
  color: var(--sb-muted) !important;
}

.sb-dashboard-chart-frame text,
.sb-dashboard-chart-frame .chart-legend {
  fill: var(--sb-muted) !important;
  color: var(--sb-muted) !important;
}

#scrollable-container .sb-dashboard-chart-frame .highcharts-background {
  fill: #0d1726 !important;
}

#scrollable-container .sb-dashboard-chart-frame .highcharts-button-box {
  fill: #152238 !important;
  stroke: var(--sb-border) !important;
}

#scrollable-container .sb-dashboard-chart-frame .highcharts-grid-line,
#scrollable-container .sb-dashboard-chart-frame .highcharts-axis-line,
#scrollable-container .sb-dashboard-chart-frame .highcharts-tick {
  stroke: var(--sb-border) !important;
}

#scrollable-container .sb-dashboard-chart-frame .highcharts-axis-labels text,
#scrollable-container .sb-dashboard-chart-frame .highcharts-axis-title,
#scrollable-container .sb-dashboard-chart-frame .highcharts-legend-item text,
#scrollable-container .sb-dashboard-chart-frame .highcharts-title,
#scrollable-container .sb-dashboard-chart-frame .highcharts-subtitle {
  fill: var(--sb-muted) !important;
}

#scrollable-container .sb-dashboard-chart-frame .highcharts-button-symbol {
  stroke: var(--sb-muted) !important;
}

#scrollable-container .sb-dashboard-chart-frame .highcharts-tooltip-box {
  fill: #152238 !important;
  stroke: var(--sb-border-strong) !important;
}

#scrollable-container .sb-dashboard-chart-frame .highcharts-tooltip text {
  fill: var(--sb-text) !important;
}

/* DataTables and date widgets are injected after page load and otherwise
   fall back to the legacy white Bootstrap skin. */
.dataTables_wrapper .dataTables_length select,
.dataTables_wrapper .dataTables_filter input,
.datepicker,
.datepicker-dropdown,
.daterangepicker,
.bootstrap-datetimepicker-widget {
  background: var(--sb-surface) !important;
  color: var(--sb-text) !important;
  border-color: var(--sb-border) !important;
  box-shadow: 0 18px 45px rgba(0, 0, 0, .3) !important;
}

.datepicker table tr td,
.datepicker table tr th,
.daterangepicker td,
.daterangepicker th,
.bootstrap-datetimepicker-widget table td,
.bootstrap-datetimepicker-widget table th {
  color: var(--sb-muted) !important;
}

.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.daterangepicker td.active,
.daterangepicker td.active:hover,
.bootstrap-datetimepicker-widget table td.active {
  background: var(--sb-accent-strong) !important;
  color: white !important;
}

/* SweetAlert (the t4t5/sweetalert confirm/alert dialogs used sitewide via
   swal() in app.js) ships in extracss.blade.php as plain vendor CSS with a
   hardcoded white modal and near-black text, and nothing in either theme
   sheet ever touched it - so "Are you sure?" and every other confirm popup
   broke the dark theme, on every page. The confirm/danger buttons already
   carry white text on a saturated fill, so they're left alone. */
.swal-overlay {
  background-color: rgba(2, 6, 15, .6) !important;
}

.swal-modal {
  background-color: var(--sb-surface) !important;
  box-shadow: 0 18px 45px rgba(0, 0, 0, .35) !important;
}

.swal-title {
  color: var(--sb-text) !important;
}

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

.swal-button--cancel {
  background-color: var(--sb-surface-raised) !important;
  color: var(--sb-text) !important;
}

.swal-button--cancel[not\:disabled]:hover {
  background-color: var(--sb-surface-hover) !important;
}

.box-header,
.box-footer,
.nav-tabs-custom > .nav-tabs,
.modal-header,
.modal-footer {
  background: rgba(255, 255, 255, .018) !important;
  border-color: var(--sb-border) !important;
  /* vendor.css sets .box-header{color:#444}. Only the background was being
     repointed here, so anything inside that does not set its own colour just
     inherited that near-black - which is how the subtitle under "All Selling
     Price Group" ended up at about 1.8:1 on the dark panel. .box-title and
     the headings were unaffected because they are coloured separately just
     below. The token resolves per theme, so light mode is unchanged. */
  color: var(--sb-text) !important;
}

/* The header sits directly on the card it titles, so the faint white wash the
   rule above gives the whole family read as a separate bar across the top of
   every box. Only .box-header is reset - .box-footer, the modal chrome and the
   tab strip still want that lift to separate them from their content. Listed
   after the group rather than pulled out of it so the border and text colour
   set there still apply; same specificity, later source order wins.

   This sheet loads in both themes, so light mode is covered too - there the
   wash was over white, and the card's own surface now shows through. */
.box-header {
  background: transparent !important;
}

/* Those subtitles are secondary text, so they take the muted tone rather
   than full-strength body colour - 7.41:1 on the dark panel. */
.box-header small,
.box-footer small {
  color: var(--sb-muted) !important;
}

.box-title,
.modal-title,
h1, h2, h3, h4, h5, h6,
.text-black,
.text-gray-900,
.tw-text-gray-900,
.tw-text-slate-900 {
  color: var(--sb-text) !important;
}

.text-muted,
.text-gray-500,
.tw-text-gray-500,
.tw-text-slate-500,
.tw-text-slate-600,
.text-gray-600,
.tw-text-gray-600,
.text-gray-700,
.tw-text-gray-700,
.text-slate-700,
.tw-text-slate-700 {
  color: var(--sb-muted) !important;
}

.tw-text-slate-400,
.tw-text-gray-400,
.text-gray-400 {
  color: var(--sb-faint) !important;
}

/* .btn excludes Bootstrap buttons that are marked up as anchors, but the app
   also has daisyUI buttons as anchors (tw-dw-btn), and those were still being
   painted as links: "Export product prices" on /update-product-price carries
   tw-text-white, yet a:not(.btn) is (0,1,1) against that class's (0,1,0) and
   won, leaving sky-300 text on the primary fill at 4.62:1. A button should
   keep its own foreground in both themes, so it is excluded here too. */
a:not(.btn):not(.tw-dw-btn) {
  color: #7dd3fc;
}

a:not(.btn):not(.tw-dw-btn):hover,
a:not(.btn):not(.tw-dw-btn):focus {
  color: #bae6fd;
}

/* Form controls and Select2 */
.form-control,
.input-group-addon,
.input-group-btn .btn,
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple,
.select2-dropdown,
.select2-search__field {
  background: #0d1726 !important;
  color: var(--sb-text) !important;
  border-color: var(--sb-border-strong) !important;
  box-shadow: none !important;
}

.form-control,
.select2-container--default .select2-selection--single {
  border-radius: 8px !important;
}

.input-group-addon:first-child,
.input-group-btn:first-child > .btn,
.input-group-btn:last-child > .btn {
  border-radius: 8px !important;
}

.form-control:focus,
.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--open .select2-selection {
  border-color: var(--sb-accent) !important;
  box-shadow: 0 0 0 3px rgba(56, 189, 248, .15) !important;
}

.form-control::placeholder,
.select2-container--default .select2-selection__placeholder {
  color: var(--sb-faint) !important;
}

.select2-container--default .select2-selection--single .select2-selection__rendered,
.select2-results__option,
.select2-container--default .select2-selection--multiple .select2-selection__choice {
  color: var(--sb-text) !important;
}

.select2-container--default .select2-results__option[aria-selected=true],
.select2-container--default .select2-results__option--highlighted[aria-selected] {
  background: rgba(56, 189, 248, .16) !important;
}

.select2-container--default .select2-selection--multiple .select2-selection__choice {
  background: #19334b !important;
  border-color: #315472 !important;
}

/* Buttons, tables and menus */
.btn,
.tw-dw-btn {
  border-radius: 8px;
  transition: transform .15s ease, filter .15s ease, background .15s ease;
}

.btn-default,
.btn-flat.btn-default {
  color: var(--sb-text) !important;
  background: #17263a !important;
  border-color: #304764 !important;
}

.btn-primary,
.bg-primary,
.label-primary {
  background: linear-gradient(135deg, #0284c7, #0369a1) !important;
  border-color: #38bdf8 !important;
  color: white !important;
}

.btn-success,
.label-success {
  background: #087c5a !important;
  border-color: #34d399 !important;
}

/* The earlier dark pass covered alert-info/warning/danger, btn-primary,
   btn-success and their label twins. The remaining stock variants were left on
   Bootstrap's light defaults -- white type on orange or pale blue -- and
   measured 1.86-2.04:1 on the dark ground. Measured replacements: warning 6.15,
   info 6.05, danger 6.68, default 8.40, alert-success 11.7-14.5. */
.btn-warning,
.label-warning {
  background: #7c5207 !important;
  border-color: #fbbf24 !important;
  color: #fef3c7 !important;
}

.btn-info,
.label-info {
  background: #0c617a !important;
  border-color: #38bdf8 !important;
  color: #d8f3ff !important;
}

.btn-danger,
.label-danger {
  background: #9f1239 !important;
  border-color: #fb7185 !important;
  color: #ffe4e6 !important;
}

.label-default {
  background: #334155 !important;
  border-color: var(--sb-border-strong) !important;
  color: #e2e8f0 !important;
}

.alert-success,
.callout.callout-success {
  background: rgba(8, 124, 90, .2) !important;
  border: 1px solid rgba(52, 211, 153, .38) !important;
  color: #d1fae5 !important;
}

/* Field guidance sat on Bootstrap's #737373 and measured 3.37:1 on a dark card. */
.help-block {
  color: var(--sb-muted) !important;
}

pre,
code,
kbd,
samp {
  background: var(--sb-surface) !important;
  border-color: var(--sb-border) !important;
  color: var(--sb-text) !important;
}

.btn:hover,
.tw-dw-btn:hover {
  filter: brightness(1.1);
}

.btn:active,
.tw-dw-btn:active {
  transform: translateY(1px);
}

.table,
.table > thead > tr > th,
.table > tbody > tr > td,
.table > tfoot > tr > td {
  color: var(--sb-text) !important;
  border-color: var(--sb-border) !important;
}

.table > thead > tr > th,
table.dataTable thead th {
  background: #132035 !important;
  color: #c9d8ea !important;
  letter-spacing: .045em;
  text-transform: uppercase;
  font-size: 11px;
}

/* Legacy tab panes and DataTables scroll wrappers keep their own Bootstrap
   white backgrounds. They sit inside the dark shell on list pages such as
   Products, so explicitly theme every generated surface and row. */
.nav-tabs-custom > .nav-tabs,
.nav-tabs-custom > .nav-tabs > li > a,
.nav-tabs-custom > .nav-tabs > li.active > a,
.nav-tabs-custom > .nav-tabs > li.active > a:hover,
.nav-tabs-custom > .nav-tabs > li.active > a:focus,
.nav-tabs-custom > .tab-content,
.nav-tabs-custom > .tab-content > .tab-pane,
.dataTables_wrapper,
.dataTables_wrapper .dataTables_scroll,
.dataTables_wrapper .dataTables_scrollHead,
.dataTables_wrapper .dataTables_scrollHeadInner,
.dataTables_wrapper .dataTables_scrollBody,
.dataTables_wrapper .dataTables_scrollFoot,
.dataTables_wrapper .dataTables_scrollFootInner,
table.dataTable,
table.dataTable tbody,
table.dataTable tbody > tr,
table.dataTable tbody > tr > td,
table.dataTable tfoot > tr > td {
  background: var(--sb-surface) !important;
  color: var(--sb-text) !important;
}

/* vendor.css sets .nav-tabs to 1px solid #ddd, then immediately weakens it to
   #f4f4f4 for .nav-tabs-custom, which all but erases the rule under the tab
   strip. --sb-border is nearly as faint (#e2e8f0 light), so the strip read as
   floating with no baseline. --sb-border-strong is the token meant for lines
   that have to be seen; width and style are restated so the vendor shorthand
   cannot leave a 0-width edge behind. */
.nav-tabs-custom > .nav-tabs {
  border-bottom: 1px solid var(--sb-border-strong) !important;
}

.nav-tabs-custom > .nav-tabs > li > a {
  border-color: transparent !important;
  color: var(--sb-muted) !important;
}

.nav-tabs-custom > .nav-tabs > li > a:hover,
.nav-tabs-custom > .nav-tabs > li > a:focus {
  background: rgba(56, 189, 248, .08) !important;
  color: var(--sb-text) !important;
}

.nav-tabs-custom > .nav-tabs > li.active > a,
.nav-tabs-custom > .nav-tabs > li.active > a:hover,
.nav-tabs-custom > .nav-tabs > li.active > a:focus {
  /* top | left and right | bottom. The side borders used to be --sb-border,
     which drew a vertical rule between the active tab and its neighbour -
     visible as a separator between "All Products" and "Stock Report". The
     active tab is already distinguished by its surface and top edge, so the
     sides are transparent; the width is unchanged, so nothing shifts. */
  border-color: var(--sb-border) transparent var(--sb-surface) !important;
  color: var(--sb-text) !important;
}

/* Product thumbnails render as display:block, so text-align on the cell
   cannot move them. Auto margins centre them instead. */
table.dataTable tbody td img.product-thumbnail-small {
  margin-left: auto;
  margin-right: auto;
}

/* Bootstrap gives checkboxes margin-top:4px and baseline alignment, which
   drops them below the centre line of a tall table row. */
table.dataTable tbody td.selectable_td input[type="checkbox"],
table.dataTable thead th input[type="checkbox"] {
  margin: 0;
  vertical-align: middle;
}

/* The theme renders these tab labels at 18px/600, which reads as a page
   heading rather than a tab. Bring them down to control size. */
.nav-tabs-custom > .nav-tabs > li > a {
  font-size: 14px !important;
  font-weight: 600 !important;
  line-height: 1.4 !important;
  padding: 8px 14px !important;
}

.nav-tabs-custom > .nav-tabs > li > a > i {
  font-size: 14px !important;
  margin-right: 4px;
}

.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter,
.dataTables_wrapper .dataTables_info {
  color: var(--sb-muted) !important;
}

.dataTables_wrapper .dataTables_scrollBody {
  border-color: var(--sb-border) !important;
}

table.dataTable tbody > tr.even,
table.dataTable tbody > tr:nth-of-type(even),
table.dataTable tbody > tr.selected {
  background: #111d2e !important;
}

table.dataTable tbody > tr.odd,
table.dataTable tbody > tr:nth-of-type(odd) {
  background: #0d1726 !important;
}

table.dataTable tbody > tr:hover,
table.dataTable tbody > tr.selected:hover {
  background: rgba(56, 189, 248, .12) !important;
}

.table-striped > tbody > tr:nth-of-type(odd),
.table-hover > tbody > tr:hover,
table.dataTable.stripe tbody tr.odd,
table.dataTable.display tbody tr.odd {
  background: rgba(255, 255, 255, .018) !important;
}

.table-hover > tbody > tr:hover,
table.dataTable.hover tbody tr:hover,
table.dataTable.display tbody tr:hover {
  background: rgba(56, 189, 248, .07) !important;
}

/* The View Product modal and stock detail partials build their tables with
   the AdminLTE light-theme utilities .bg-gray (light gray body) and
   tr.bg-green (green strip, white text at ~2.1:1). The .content-scoped rule
   below misses any modal appended outside .content, so anchor these on the
   table itself and give both headers the same dark treatment. */
table.bg-gray,
table.bg-gray > thead > tr,
table.bg-gray > thead > tr > th,
table.bg-gray > tbody > tr,
table.bg-gray > tbody > tr > td {
  background: var(--sb-surface) !important;
  color: var(--sb-text) !important;
  border-color: var(--sb-border) !important;
}

table.bg-gray > thead > tr.bg-green,
table.bg-gray > thead > tr.bg-green > th,
table.bg-gray > tbody > tr.bg-green,
table.bg-gray > tbody > tr.bg-green > th {
  background: var(--sb-surface-raised) !important;
  color: var(--sb-text) !important;
  border-color: var(--sb-border-strong) !important;
}

/* Variation, price and stock cells in the product detail modals are all short
   values (prices, SKUs, quantities), so centre them. Headers follow so they
   stay lined up over their columns. Scoped to .modal rather than to
   #view_product_modal: the modal actually shown is built as
   <div class="modal fade view_modal"> with no id, and #view_product_modal is
   a separate hidden element. Report pages reuse .bg-gray for left-aligned
   totals rows, but those live in .content, never in a modal. */
.modal table.bg-gray > thead > tr > th,
.modal table.bg-gray > tbody > tr > th,
.modal table.bg-gray > tbody > tr > td {
  text-align: center !important;
  vertical-align: middle !important;
  white-space: nowrap;
}

/* With nowrap the table sizes to its content and can exceed the modal, so the
   wrapper has to scroll. Bootstrap 3 only enables this below 768px. */
.modal .table-responsive {
  overflow-x: auto;
}

.modal table.bg-gray img {
  margin-left: auto;
  margin-right: auto;
}

/* Report totals use the legacy .bg-gray class, which otherwise paints a
   light gray strip with white text. Keep totals readable and consistent with
   the dark report surface. */
.content .bg-gray,
.content .footer-total,
.content .footer-total > td,
.content table > tfoot > tr,
.content table > tfoot > tr > td,
table.dataTable tfoot > tr,
table.dataTable tfoot > tr > td {
  background: #1b2b43 !important;
  border-color: var(--sb-border-strong) !important;
  color: var(--sb-text) !important;
}

.content .footer-total strong,
.content .footer-total span,
.content .footer-total .display_currency {
  color: var(--sb-text) !important;
}

.dataTables_wrapper .dataTables_scrollBody {
  scrollbar-color: #34506f #0b1422;
  scrollbar-width: thin;
}

.dataTables_wrapper .dataTables_scrollBody::-webkit-scrollbar {
  width: 9px;
  height: 9px;
}

.dataTables_wrapper .dataTables_scrollBody::-webkit-scrollbar-track {
  background: #0b1422;
}

.dataTables_wrapper .dataTables_scrollBody::-webkit-scrollbar-thumb {
  background: #34506f;
  border: 2px solid #0b1422;
  border-radius: 999px;
}

.dataTables_wrapper .dataTables_scrollBody::-webkit-scrollbar-thumb:hover {
  background: #4f7097;
}

.content .table-responsive {
  scrollbar-color: #34506f #0b1422;
  scrollbar-width: thin;
}

.content .table-responsive::-webkit-scrollbar {
  width: 9px;
  height: 9px;
}

.content .table-responsive::-webkit-scrollbar-track {
  background: #0b1422;
}

.content .table-responsive::-webkit-scrollbar-thumb {
  background: #34506f;
  border: 2px solid #0b1422;
  border-radius: 999px;
}

/* The dashboard cards scroll their tables in a Tailwind wrapper
   (.tw-overflow-x-auto) rather than .table-responsive, so they were the one
   place still showing the browser's default 15px bar next to the 9px one used
   everywhere else. Same treatment, same measurements. */
#scrollable-container .tw-overflow-x-auto {
  scrollbar-color: #34506f #0b1422;
  scrollbar-width: thin;
}

#scrollable-container .tw-overflow-x-auto::-webkit-scrollbar {
  width: 9px;
  height: 9px;
}

#scrollable-container .tw-overflow-x-auto::-webkit-scrollbar-track {
  background: #0b1422;
}

#scrollable-container .tw-overflow-x-auto::-webkit-scrollbar-thumb {
  background: #34506f;
  border: 2px solid #0b1422;
  border-radius: 999px;
}

#scrollable-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover {
  background: #4f7097;
}

.content .table-responsive::-webkit-scrollbar-thumb:hover {
  background: #4f7097;
}

/* Most report charts are rendered directly into a widget rather than the
   dashboard chart frame. Apply the same dark Highcharts palette to both. */
.content .chart-container,
.content .highcharts-container,
.content svg.highcharts-root {
  background: #0d1726 !important;
}

.content .highcharts-background,
.content .highcharts-plot-background,
.content .highcharts-pane {
  fill: #0d1726 !important;
}

.content .highcharts-grid-line,
.content .highcharts-axis-line,
.content .highcharts-tick {
  stroke: var(--sb-border) !important;
}

.content .highcharts-axis-labels text,
.content .highcharts-axis-title,
.content .highcharts-data-labels text,
.content .highcharts-legend-item text,
.content .highcharts-title,
.content .highcharts-subtitle {
  fill: var(--sb-muted) !important;
  color: var(--sb-muted) !important;
}

.content .highcharts-button-box {
  fill: #152238 !important;
  stroke: var(--sb-border) !important;
}

.content .highcharts-button-symbol {
  stroke: var(--sb-muted) !important;
}

.content .highcharts-tooltip-box {
  fill: #152238 !important;
  stroke: var(--sb-border-strong) !important;
}

.content .highcharts-tooltip text {
  fill: var(--sb-text) !important;
}

.pagination > li > a,
.pagination > li > span,
.dataTables_wrapper .dataTables_paginate .paginate_button {
  background: #142237 !important;
  border-color: var(--sb-border) !important;
  color: var(--sb-muted) !important;
}

.pagination > .active > a,
.dataTables_wrapper .dataTables_paginate .paginate_button.current {
  background: #0e7490 !important;
  border-color: #38bdf8 !important;
  color: white !important;
}

.dropdown-menu > li > a,
.tw-dw-menu a {
  color: var(--sb-muted) !important;
}

.dropdown-menu > li > a:hover,
.tw-dw-menu a:hover {
  background: rgba(56, 189, 248, .1) !important;
  color: var(--sb-text) !important;
}

.modal-header .close,
.close {
  color: var(--sb-text) !important;
  opacity: .75;
}

/* Dashboard cards retain their information hierarchy in dark mode.
   Modals are appended to <body>, outside .content, so they need the same
   surface treatment or light-mode cards keep near-white text unreadable. */
.content .tw-bg-white,
.content .tw-bg-gray-100,
.content .tw-bg-slate-100,
.content .tw-bg-base-100,
.modal .tw-bg-white,
.modal .tw-bg-gray-100,
.modal .tw-bg-slate-100,
.modal .tw-bg-base-100 {
  background: var(--sb-surface) !important;
  border-color: var(--sb-border) !important;
}

.content .tw-ring-gray-200,
.content .tw-border-gray-200,
.content .tw-border-slate-200,
.modal .tw-ring-gray-200,
.modal .tw-border-gray-200,
.modal .tw-border-slate-200 {
  --tw-ring-color: var(--sb-border) !important;
  border-color: var(--sb-border) !important;
}

.content .tw-shadow-sm,
.content .tw-shadow-md,
.content .tw-shadow-\[rgba\(17\,_17\,_26\,_0\.1\)_0px_0px_16px\] {
  box-shadow: 0 14px 30px rgba(0, 0, 0, .2) !important;
}

/* Dashboard presentation layer: existing data hooks, permissions and live charts
   remain untouched. */
.saverbro-dashboard {
  --sb-dashboard-card: rgba(16, 27, 45, .92);
  --sb-dashboard-card-border: rgba(86, 116, 153, .25);
  --sb-dashboard-blue: #38bdf8;
  --sb-dashboard-blue-deep: #075985;
  --sb-dashboard-copy: #eef6ff;
  --sb-dashboard-muted: #93a7bf;
  background: transparent !important;
}

.saverbro-dashboard > .tw-relative > .tw-absolute .tw-bg-gray-100 {
  background: #0a1321 !important;
}

.saverbro-dashboard > .tw-px-5,
.saverbro-dashboard > .tw-relative > .tw-px-5,
.saverbro-dashboard + .tw-px-5 {
  max-width: 1720px;
  margin-left: auto;
  margin-right: auto;
}

.saverbro-dashboard > .tw-px-5 {
  padding-top: 1.5rem;
}

.sb-dashboard-intro {
  position: relative;
}

.sb-dashboard-eyebrow {
  margin: 0 0 .28rem;
  color: #7dd3fc !important;
  font-size: .65rem;
  font-weight: 700;
  letter-spacing: .14em;
  line-height: 1.25;
  text-transform: uppercase;
}

.sb-dashboard-intro h1 {
  margin: 0;
  color: var(--sb-dashboard-copy) !important;
  font-size: clamp(1.65rem, 2.2vw, 2.15rem) !important;
  line-height: 1.15;
}

.sb-dashboard-welcome {
  margin: .4rem 0 0;
  color: var(--sb-dashboard-muted) !important;
  font-size: .9rem;
}

.sb-dashboard-header-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2rem;
  padding: 1rem 1.2rem 1.15rem;
  border: 1px solid rgba(86, 116, 153, .28);
  border-radius: 1rem;
  background: linear-gradient(112deg, rgba(12, 31, 52, .82), rgba(7, 17, 30, .7));
}

.sb-dashboard-header-row .sb-dashboard-intro {
  flex: 1 1 auto;
  min-width: 0;
}

.sb-dashboard-header-filters {
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  gap: .8rem;
  flex: 0 1 42rem;
  min-width: 0;
}

.sb-dashboard-filter-control {
  flex: 1 1 15rem;
  min-width: 12rem;
}

.sb-dashboard-filter-control--date {
  flex: 0 0 13rem;
}

.sb-dashboard-filter-label {
  display: block;
  margin: 0 0 .35rem .1rem;
  color: var(--sb-dashboard-muted);
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .1em;
  line-height: 1.2;
  text-transform: uppercase;
}

/* The #dashboard_location half styles the raw <select> before select2 has
   initialised, so it does not flash at its default width. Once select2 takes
   over it hides the original with .select2-hidden-accessible (1x1px, clipped)
   - but that rule is (0,1,0) and this one is (1,1,0), so the hidden select
   stayed 1276px wide, absolutely positioned at x=563. Invisible, but it still
   measured, pushing the main scroller's content to 1839px and giving the
   dashboard a horizontal scrollbar that slid the KPI cards under the sidebar.
   The :not() hands control back to select2 the moment it initialises. */
.sb-dashboard-filter-control .select2-container,
.sb-dashboard-filter-control #dashboard_location:not(.select2-hidden-accessible) {
  width: 100% !important;
}

.sb-dashboard-filter-button {
  width: 100% !important;
  min-height: 2.75rem;
  border: 1px solid rgba(125, 211, 252, .2) !important;
  background: rgba(8, 17, 31, .7) !important;
  color: var(--sb-dashboard-copy) !important;
  box-shadow: none !important;
}

.sb-dashboard-filter-button:hover,
.sb-dashboard-filter-button:focus {
  border-color: rgba(56, 189, 248, .58) !important;
  background: rgba(14, 55, 87, .72) !important;
}

/* Same pre-select2 treatment, same exclusion: min-height was keeping the
   hidden original 44px tall instead of 1px. */
.saverbro-dashboard #dashboard_location:not(.select2-hidden-accessible),
.saverbro-dashboard #dashboard_date_filter {
  min-height: 2.75rem;
  border: 1px solid rgba(125, 211, 252, .2) !important;
  border-radius: .7rem !important;
  background: rgba(8, 17, 31, .7) !important;
  color: var(--sb-dashboard-copy) !important;
  box-shadow: none !important;
}

.saverbro-dashboard #dashboard_date_filter:hover,
.saverbro-dashboard #dashboard_date_filter:focus {
  border-color: rgba(56, 189, 248, .58) !important;
  background: rgba(14, 55, 87, .72) !important;
}

.saverbro-dashboard .select2-container--default .select2-selection--single {
  min-height: 2.75rem;
  border-color: rgba(125, 211, 252, .2) !important;
  background: rgba(8, 17, 31, .7) !important;
}

.saverbro-dashboard .select2-container--default .select2-selection--single .select2-selection__rendered {
  line-height: 2.6rem;
}

.saverbro-dashboard .select2-container--default .select2-selection--single .select2-selection__arrow {
  height: 2.65rem;
}

/* KPI blocks deliberately retain their real total_* hooks and differ only by tone. */
.saverbro-dashboard .sb-dashboard-metrics > div,
.saverbro-dashboard > .tw-relative .xl\:tw-grid-cols-4 > div {
  position: relative;
  overflow: hidden;
  min-height: 8.1rem;
  border: 1px solid rgba(255,255,255,.08) !important;
  border-radius: .8rem !important;
  background: rgba(22, 32, 54, .85) !important;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .18) !important;
}

.saverbro-dashboard .sb-dashboard-metrics > div::after,
.saverbro-dashboard > .tw-relative .xl\:tw-grid-cols-4 > div::after {
  content: none;
}

.saverbro-dashboard .tw-grid > div > .tw-p-4,
.saverbro-dashboard .tw-grid > div > .sm\:tw-p-5 {
  position: relative;
  z-index: 1;
}

.saverbro-dashboard .tw-grid > div > div > div > .tw-inline-flex {
  border: 1px solid rgba(186, 230, 253, .18);
  border-radius: .8rem !important;
  background: rgba(56, 189, 248, .13) !important;
  color: #7dd3fc !important;
}

.saverbro-dashboard .total_sell,
.saverbro-dashboard .net,
.saverbro-dashboard .invoice_due,
.saverbro-dashboard .total_sell_return,
.saverbro-dashboard .total_purchase,
.saverbro-dashboard .total_purchase_return,
.saverbro-dashboard .total_expense {
  color: var(--sb-dashboard-copy) !important;
  font-size: 1.4rem !important;
  letter-spacing: -.03em;
}

.sb-dashboard-kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1rem;
  margin-bottom: 1.25rem;
}

/* Loyverse-style KPI cards - accent colour now covers the whole card
   (tinted background + full border), not just a left strip. */
.sb-dashboard-kpi {
  position: relative;
  display: flex;
  min-height: 7rem;
  align-items: center;
  gap: 1rem;
  overflow: hidden;
  padding: 1.25rem;
  border: 1.5px solid #4caf50;
  border-radius: .85rem;
  background: #f0fdf4;
  box-shadow: 0 1px 4px rgba(0,0,0,.06);
  color: #1e293b;
  transition: box-shadow .15s ease, transform .15s ease;
}
.sb-dashboard-kpi:hover {
  box-shadow: 0 4px 16px rgba(0,0,0,.1);
  transform: translateY(-1px);
}
.sb-dashboard-kpi::after { content: none; }

.sb-dashboard-kpi--purchase    { border-color: #8b5cf6; background: #f5f3ff; }
.sb-dashboard-kpi--due         { border-color: #f59e0b; background: #fffbeb; }
.sb-dashboard-kpi--visits      { border-color: #0ea5e9; background: #f0f9ff; }
.sb-dashboard-kpi--transactions { border-color: #06b6d4; background: #ecfeff; }
.sb-dashboard-kpi--expenses    { border-color: #64748b; background: #f8fafc; }
.sb-dashboard-kpi--returns     { border-color: #ef4444; background: #fef2f2; }
.sb-dashboard-kpi--adjustments { border-color: #d97706; background: #fffbeb; }

/* True dark theme: tinted-white backgrounds above are unreadable on a dark
   page shell, so give the cards a dark surface (same --sb-surface-raised
   used elsewhere in dark mode) with the accent as a full border + a subtle
   tinted overlay instead of a solid light fill. */
html[data-theme="dark"] .sb-dashboard-kpi {
  background: var(--sb-surface-raised);
  border-color: #4caf50;
  color: var(--sb-text);
  box-shadow: 0 1px 4px rgba(0,0,0,.35);
}
html[data-theme="dark"] .sb-dashboard-kpi--purchase     { border-color: #a78bfa; background: linear-gradient(0deg, rgba(139,92,246,.12), rgba(139,92,246,.12)), var(--sb-surface-raised); }
html[data-theme="dark"] .sb-dashboard-kpi--due           { border-color: #fbbf24; background: linear-gradient(0deg, rgba(245,158,11,.12), rgba(245,158,11,.12)), var(--sb-surface-raised); }
html[data-theme="dark"] .sb-dashboard-kpi--visits        { border-color: #38bdf8; background: linear-gradient(0deg, rgba(14,165,233,.12), rgba(14,165,233,.12)), var(--sb-surface-raised); }
html[data-theme="dark"] .sb-dashboard-kpi--transactions  { border-color: #22d3ee; background: linear-gradient(0deg, rgba(6,182,212,.12), rgba(6,182,212,.12)), var(--sb-surface-raised); }
html[data-theme="dark"] .sb-dashboard-kpi--expenses      { border-color: #94a3b8; background: linear-gradient(0deg, rgba(100,116,139,.15), rgba(100,116,139,.15)), var(--sb-surface-raised); }
html[data-theme="dark"] .sb-dashboard-kpi--returns       { border-color: #f87171; background: linear-gradient(0deg, rgba(239,68,68,.12), rgba(239,68,68,.12)), var(--sb-surface-raised); }
html[data-theme="dark"] .sb-dashboard-kpi--adjustments   { border-color: #fbbf24; background: linear-gradient(0deg, rgba(217,119,6,.14), rgba(217,119,6,.14)), var(--sb-surface-raised); }
html[data-theme="dark"] .sb-dashboard-kpi:hover { background-color: var(--sb-surface-hover); }
html[data-theme="dark"] .sb-dashboard-kpi__value { color: var(--sb-text) !important; }
html[data-theme="dark"] .sb-dashboard-kpi__label { color: var(--sb-text) !important; opacity: .85; }
html[data-theme="dark"] .sb-dashboard-kpi__hint  { color: var(--sb-muted) !important; }

.sb-dashboard-kpi__icon {
  position: relative;
  z-index: 1;
  display: inline-flex;
  width: 2.75rem;
  height: 2.75rem;
  flex: 0 0 2.75rem;
  align-items: center;
  justify-content: center;
  border-radius: .7rem;
  background: #f0fdf4;
  color: #4caf50;
  font-size: 1.2rem;
}
.sb-dashboard-kpi--purchase    .sb-dashboard-kpi__icon { background:#f5f3ff; color:#8b5cf6; }
.sb-dashboard-kpi--due         .sb-dashboard-kpi__icon { background:#fffbeb; color:#f59e0b; }
.sb-dashboard-kpi--visits      .sb-dashboard-kpi__icon { background:#f0f9ff; color:#0ea5e9; }
.sb-dashboard-kpi--transactions .sb-dashboard-kpi__icon { background:#ecfeff; color:#06b6d4; }
.sb-dashboard-kpi--expenses    .sb-dashboard-kpi__icon { background:#f8fafc; color:#64748b; }
.sb-dashboard-kpi--returns     .sb-dashboard-kpi__icon { background:#fef2f2; color:#ef4444; }
.sb-dashboard-kpi--adjustments .sb-dashboard-kpi__icon { background:#fffbeb; color:#d97706; }

/* Dark theme: solid-colour icon chip reads better against the dark tinted
   card than the pale pastel chip used on light backgrounds. */
html[data-theme="dark"] .sb-dashboard-kpi__icon                            { background:#4caf50; color:#06240c; }
html[data-theme="dark"] .sb-dashboard-kpi--purchase    .sb-dashboard-kpi__icon { background:#a78bfa; color:#2e1065; }
html[data-theme="dark"] .sb-dashboard-kpi--due         .sb-dashboard-kpi__icon { background:#fbbf24; color:#451a03; }
html[data-theme="dark"] .sb-dashboard-kpi--visits      .sb-dashboard-kpi__icon { background:#38bdf8; color:#082f49; }
html[data-theme="dark"] .sb-dashboard-kpi--transactions .sb-dashboard-kpi__icon { background:#22d3ee; color:#083344; }
html[data-theme="dark"] .sb-dashboard-kpi--expenses    .sb-dashboard-kpi__icon { background:#94a3b8; color:#1e293b; }
html[data-theme="dark"] .sb-dashboard-kpi--returns     .sb-dashboard-kpi__icon { background:#f87171; color:#450a0a; }
html[data-theme="dark"] .sb-dashboard-kpi--adjustments .sb-dashboard-kpi__icon { background:#fbbf24; color:#451a03; }

.sb-dashboard-kpi__content {
  position: relative;
  z-index: 1;
  flex: 1 1 auto;
  min-width: 0;
}

.sb-dashboard-kpi__label,
.sb-dashboard-kpi__value,
.sb-dashboard-kpi__hint {
  margin: 0;
}

/* Low Stock Alert dashboard widget (home/index.blade.php) - plain Tailwind
   utility classes with no dark variant, so the text stayed dark-gray against
   a dark card and was effectively invisible. */
html[data-theme="dark"] #low-stock-alert-card {
  background: var(--sb-surface-raised) !important;
  box-shadow: 0 1px 4px rgba(0,0,0,.35) !important;
}
html[data-theme="dark"] #low-stock-alert-card .tw-bg-amber-50 {
  background: rgba(245,158,11,.12) !important;
  border-color: rgba(245,158,11,.25) !important;
}
html[data-theme="dark"] #low-stock-alert-card .tw-bg-amber-100 {
  background: rgba(245,158,11,.22) !important;
}
html[data-theme="dark"] #low-stock-alert-card .tw-text-amber-800,
html[data-theme="dark"] #low-stock-alert-card .tw-text-amber-700,
html[data-theme="dark"] #low-stock-alert-card .tw-text-amber-600 {
  color: #fbbf24 !important;
}
html[data-theme="dark"] #low-stock-list .tw-text-gray-800 {
  color: var(--sb-text) !important;
}
html[data-theme="dark"] #low-stock-list .tw-text-gray-500,
html[data-theme="dark"] #low-stock-list .tw-text-gray-400 {
  color: var(--sb-muted) !important;
}
html[data-theme="dark"] #low-stock-list .tw-bg-gray-100 {
  background: rgba(255,255,255,.14) !important;
}
html[data-theme="dark"] #low-stock-list > div:hover {
  background: var(--sb-surface-hover) !important;
}

.sb-dashboard-kpi__label {
  color: #6b7280;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .08em;
  line-height: 1.25;
  min-height: 1.75rem;
  text-transform: uppercase;
}

.sb-dashboard-kpi__value {
  margin-top: .25rem;
  color: #111827 !important;
  font-size: clamp(1.25rem, 1.7vw, 1.65rem);
  font-weight: 800;
  letter-spacing: -.04em;
  line-height: 1.1;
  white-space: nowrap;
}

.sb-dashboard-kpi__hint {
  margin-top: .35rem;
  color: #9ca3af;
  font-size: .72rem;
  line-height: 1.35;
  min-height: 1.8rem;
}

.sb-walk-in-card {
  position: relative;
  overflow: hidden;
  border-color: #e5e7eb !important;
  border-left: 4px solid #0ea5e9 !important;
  background: #fff !important;
  box-shadow: 0 1px 4px rgba(0,0,0,.06) !important;
  color: #1e293b !important;
}

.sb-walk-in-card:hover {
  border-color: #bae6fd !important;
  box-shadow: 0 4px 16px rgba(0,0,0,.1) !important;
}

.sb-walk-in-card p,
.sb-walk-in-card small {
  color: #6b7280 !important;
}

.sb-walk-in-card strong {
  color: #111827 !important;
  font-size: 1.1rem;
}

.sb-walk-in-card .tw-text-primary-600 {
  color: #4caf50 !important;
}

.sb-walk-in-card__stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .75rem;
}

@media (min-width: 640px) {
  .sb-walk-in-card__stats {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
}

.saverbro-dashboard + .tw-px-5 {
  padding-top: 1.75rem !important;
}

.saverbro-dashboard #dashboard_date_filter:focus-visible,
.saverbro-dashboard .select2-container--default .select2-selection--single:focus-visible {
  outline: 2px solid #7dd3fc;
  outline-offset: 3px;
}

.saverbro-dashboard + .tw-px-5 > .tw-grid > div {
  border: 1px solid var(--sb-dashboard-card-border) !important;
  border-radius: .85rem !important;
  background: var(--sb-dashboard-card) !important;
  box-shadow: 0 14px 32px rgba(0, 0, 0, .2) !important;
}

.saverbro-dashboard + .tw-px-5 > .tw-grid > div:hover {
  border-color: rgba(56, 189, 248, .4) !important;
  box-shadow: 0 18px 36px rgba(0, 0, 0, .26) !important;
}

.saverbro-dashboard + .tw-px-5 .tw-border-dashed {
  border-color: rgba(90, 127, 165, .34) !important;
  background: linear-gradient(180deg, rgba(11, 24, 41, .78), rgba(9, 17, 29, .74)) !important;
}

.saverbro-dashboard + .tw-px-5 .tw-border-2.tw-rounded-full {
  border-color: rgba(56, 189, 248, .38) !important;
  background: rgba(56, 189, 248, .07);
}

@media (max-width: 767px) {
  .saverbro-dashboard > .tw-px-5,
  .saverbro-dashboard > .tw-relative > .tw-px-5,
  .saverbro-dashboard + .tw-px-5 {
    padding-left: 1rem !important;
    padding-right: 1rem !important;
  }

  .sb-dashboard-welcome {
    margin-bottom: 1rem;
  }

  .sb-dashboard-header-row {
    align-items: stretch;
    flex-direction: column;
    gap: 1.25rem;
    padding: 1rem;
  }

  .sb-dashboard-header-filters {
    align-items: stretch;
    flex: 1 1 auto;
    flex-direction: column;
    gap: .85rem;
  }

  .sb-dashboard-filter-control,
  .sb-dashboard-filter-control--date {
    flex: 1 1 auto;
    min-width: 0;
    width: 100%;
  }

  .sb-dashboard-kpi-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .sb-dashboard-kpi {
    min-height: 7.5rem;
    padding: 1rem;
  }

}

@media (max-width: 480px) {
  .sb-dashboard-kpi-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (prefers-reduced-motion: reduce) {
  .saverbro-dashboard * {
    scroll-behavior: auto !important;
    transition-duration: .01ms !important;
  }
}

/* Auth surface uses the same dark contrast system as the signed-in shell. */
.right-col .tw-bg-white {
  background: var(--sb-surface) !important;
  border: 1px solid var(--sb-border) !important;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .32) !important;
}

.right-col .tw-text-black,
.right-col .tw-text-\[\#1e1e1e\],
.right-col .tw-text-gray-500,
.right-col .tw-text-transparent {
  color: var(--sb-text) !important;
}

.right-col input.tw-text-black,
.right-col input.tw-bg-transparent {
  background: #0d1726 !important;
  color: var(--sb-text) !important;
  border-color: var(--sb-border-strong) !important;
}

.right-col input::placeholder {
  color: var(--sb-faint) !important;
}

.right-col #show_hide_icon {
  color: var(--sb-muted) !important;
}

.right-col #show_hide_icon svg {
  stroke: var(--sb-muted) !important;
}

.right-col .tw-dw-checkbox {
  accent-color: var(--sb-accent-strong);
}

/* POS checkout: high contrast controls, a two-surface workspace, unmistakable pay action. */
body.lockscreen,
body.lockscreen #scrollable-container,
body.lockscreen .content {
  background: var(--sb-bg) !important;
}

body.lockscreen .pos-header > div,
body.lockscreen #add_pos_sell_form .tw-bg-white,
body.lockscreen #edit_pos_sell_form .tw-bg-white,
body.lockscreen .pos-sidebar-root {
  background: var(--sb-surface) !important;
  border: 1px solid var(--sb-border) !important;
  box-shadow: 0 14px 32px rgba(0, 0, 0, .24) !important;
}

body.lockscreen .pos-header > div,
body.lockscreen #add_pos_sell_form > .row > .col-md-12 > .row > div > div,
body.lockscreen #edit_pos_sell_form > .row > .col-md-12 > .row > div > div,
body.lockscreen .pos-sidebar-root {
  border-radius: 12px !important;
}

body.lockscreen #add_pos_sell_form .box-body,
body.lockscreen #edit_pos_sell_form .box-body {
  background: transparent !important;
}

body.lockscreen .pos-header .tw-bg-white,
body.lockscreen #pos_header_more_options .tw-bg-white,
body.lockscreen .pos-sidebar-root .tw-bg-white {
  background: #122137 !important;
  border-color: #2c4562 !important;
  color: var(--sb-text) !important;
}

body.lockscreen #pos_table thead th,
body.lockscreen #pos_table thead .tw-bg-\[\#f8fafc\] {
  background: #14243a !important;
  color: #91a8c5 !important;
  border-color: var(--sb-border) !important;
}

body.lockscreen #pos_table > tbody > tr > td,
body.lockscreen #pos_table > tbody > tr:nth-child(odd),
body.lockscreen #pos_table > tbody > tr:nth-child(even) {
  background: transparent !important;
  border-color: var(--sb-border) !important;
}

body.lockscreen .pos_form_totals {
  background: #0d1929 !important;
  border-top: 1px solid var(--sb-border) !important;
}

body.lockscreen .pos_form_totals .pos_totals_left,
body.lockscreen .pos_form_totals .pos_totals_cell {
  background: #111d2e !important;
  border-color: var(--sb-border) !important;
}

body.lockscreen .pos_totals_label {
  color: var(--sb-muted) !important;
}

body.lockscreen .pos_totals_value,
body.lockscreen .pos_totals_right_value,
body.lockscreen #total_payable {
  color: var(--sb-text) !important;
}

body.lockscreen .pos_totals_right_label {
  color: #a7f3d0 !important;
}

body.lockscreen .pos_totals_value--danger {
  color: var(--sb-danger) !important;
}

body.lockscreen .pos_totals_value--loyalty {
  color: #c4b5fd !important;
}

body.lockscreen .pos_totals_right {
  background: linear-gradient(135deg, #075985, #0c4a6e) !important;
  border-radius: 10px;
}

body.lockscreen .pos-form-actions {
  background: rgba(12, 20, 34, .96) !important;
  border-top: 1px solid var(--sb-border) !important;
  box-shadow: 0 -12px 35px rgba(0, 0, 0, .28) !important;
  backdrop-filter: blur(12px);
}

body.lockscreen .pos-footer-divider,
body.lockscreen .pos-nav-divider {
  background: var(--sb-border) !important;
}

body.lockscreen .pos-footer-secondary button,
body.lockscreen .pos-form-actions .tw-text-gray-700 {
  color: var(--sb-muted) !important;
}

body.lockscreen .pos-finalize {
  background: linear-gradient(135deg, #0284c7, #075985) !important;
  box-shadow: 0 8px 22px rgba(2, 132, 199, .28);
}

/* Suspend and Credit Sale. The label and icon have to be pinned white
   here: in dark mode the footer's own label colour won, leaving #97a9c1
   on #059669 at 1.57:1 - the words were effectively invisible. The
   gradient also drops one emerald step (600->700 becomes 700->800),
   because white on the old #059669 was only 3.77:1, and these labels are
   bold 14px, too small to claim the large-text allowance. The new sweep
   holds white at 5.49:1 to 7.69:1. */
body.lockscreen .pos-express-finalize:not(.pos-finalize) {
  background: linear-gradient(135deg, #047857, #065f46) !important;
}

body.lockscreen .pos-express-finalize:not(.pos-finalize),
body.lockscreen .pos-express-finalize:not(.pos-finalize) i {
  color: #ffffff !important;
}

body.lockscreen #product_list_body::-webkit-scrollbar-thumb,
body.lockscreen .pos-drawer-body::-webkit-scrollbar-thumb {
  background: #34506f !important;
}

body.lockscreen .pos-card,
body.lockscreen .pos-drawer-panel {
  background: var(--sb-surface) !important;
  border-color: var(--sb-border) !important;
}

body.lockscreen .pos-card:hover {
  background: var(--sb-surface-hover) !important;
  border-color: var(--sb-accent) !important;
  box-shadow: 0 12px 26px rgba(0, 0, 0, .22) !important;
}

body.lockscreen .pos-card.is-active.cat,
body.lockscreen .pos-card.is-active.brand {
  background: linear-gradient(180deg, #12344e, #101827 72%) !important;
  border-color: var(--sb-accent) !important;
}

body.lockscreen .pos-card-name {
  color: var(--sb-text) !important;
}

/* Subcategory pill strip (injected below a tapped category card). app.css
   hardcodes it to a light indigo wash (#eef2ff) with white pills, since
   that's the only rule that ever existed for it - so it rendered as a pale
   card floating inside the otherwise dark drawer. */
body.lockscreen .pos-subcat-strip {
  background: var(--sb-surface-raised) !important;
  border-color: var(--sb-border-strong) !important;
}

body.lockscreen .pos-subcat-pill {
  background: var(--sb-surface) !important;
  border-color: var(--sb-border-strong) !important;
  color: var(--sb-accent) !important;
}

body.lockscreen .pos-subcat-pill:active,
body.lockscreen .pos-subcat-pill.is-active {
  background: #4f46e5 !important;
  border-color: #4f46e5 !important;
  color: #ffffff !important;
}

body.lockscreen .product_box {
  background: #142237 !important;
  border-color: var(--sb-border) !important;
  box-shadow: 0 5px 14px rgba(0, 0, 0, .18) !important;
}

body.lockscreen .product_box:hover {
  background: var(--sb-surface-hover) !important;
  border-color: var(--sb-accent) !important;
}

body.lockscreen .product_box .text-muted {
  color: var(--sb-muted) !important;
}

body.lockscreen .product_box .product_price {
  color: #6ee7b7 !important;
}

/* Business Settings is built on the older pos-tab layout. Its content pane
   and list-group retain Bootstrap's white skin unless they are themed
   explicitly. */
div.pos-tab-container,
div.pos-tab-container .pos-tab,
div.pos-tab-container .pos-tab-menu,
div.pos-tab-container .pos-tab-menu .list-group,
div.pos-tab-container div.pos-tab-content {
  background: var(--sb-surface) !important;
  border-color: var(--sb-border) !important;
  color: var(--sb-text) !important;
}

div.pos-tab-container {
  box-shadow: 0 18px 45px rgba(0, 0, 0, .28) !important;
}

div.pos-tab-menu div.list-group > a,
div.pos-tab-menu div.list-group > a:hover,
div.pos-tab-menu div.list-group > a:focus {
  background: #111d2e !important;
  border-color: var(--sb-border) !important;
  color: var(--sb-text) !important;
}

div.pos-tab-menu div.list-group > a.active,
div.pos-tab-menu div.list-group > a.active:hover,
div.pos-tab-menu div.list-group > a.active:focus {
  background: linear-gradient(135deg, #075985, #0c4a6e) !important;
  border-color: var(--sb-accent) !important;
  color: #f0f9ff !important;
}

div.pos-tab-content label,
div.pos-tab-content .checkbox label,
div.pos-tab-content .control-label {
  color: var(--sb-muted) !important;
}

div.pos-tab-content .form-group > label,
div.pos-tab-content .checkbox label {
  color: var(--sb-text) !important;
}

div.pos-tab-content .input-group-addon {
  background: #122137 !important;
  color: var(--sb-muted) !important;
  border-color: var(--sb-border-strong) !important;
}

body.lockscreen #featured_products_box:not(:empty) {
  background: rgba(146, 94, 8, .17) !important;
  border-color: rgba(251, 191, 36, .35) !important;
}

body.lockscreen #featured_products_box:not(:empty)::before {
  color: #fcd34d !important;
}

@media (max-width: 767px) {
  body.lockscreen .content {
    padding-left: 4px !important;
    padding-right: 4px !important;
  }

  body.lockscreen .pos-header > div {
    border-radius: 9px !important;
  }
}

/* Table headings read as column labels, so centre them across every table. */
table.dataTable thead th,
table.dataTable thead td,
.dataTables_scrollHead table thead th,
.table > thead > tr > th {
  text-align: center;
}

/* A DataTable is the widest thing on these pages, and it was losing roughly
   90px to three nested layers of padding (section, widget, table wrapper)
   before it even began. Collapse the inner gutters when a widget is wrapping a
   table; section.content still keeps the page off the window edge. */
.content div:has(> .table-responsive) {
  padding-left: 0;
  padding-right: 0;
}

.content div:has(> div > .table-responsive) > .tw-p-2,
.content div:has(.dataTables_wrapper) > .tw-p-2 {
  padding-left: 4px;
  padding-right: 4px;
}

/* Action cells hold controls rather than data, so they read better centred under
   their heading. Two shapes exist: a .btn-group wrapper (dropdown-style action
   menus) and bare buttons/links (Edit / View / Delete rows). */
table.dataTable tbody td:has(> .btn-group),
table.dataTable tbody td:has(> .btn-group-vertical),
table.dataTable tbody td:has(> .tw-dw-btn) {
  text-align: center;
}

/* Row height is driven by whichever cell wraps the most (usually the address),
   so without this the short cells hang off the top of a tall row. */
table.dataTable thead th,
table.dataTable thead td,
table.dataTable tbody th,
table.dataTable tbody td,
table.dataTable tfoot th,
table.dataTable tfoot td {
  vertical-align: middle;
}

/* Column widths are widened proportionally in table-colresize.js rather than
   with a min-width here: a flat floor makes DataTables equalise every column,
   so Address and Pay term end up identical. */

/* Resizing only behaves if the browser treats the declared column widths as
   authoritative. Under the default auto layout it redistributes widths from
   cell content, so a dragged column springs back and the header drifts out of
   step with the body. DataTables already sets an explicit width on every
   column in scroll mode, so fixed layout honours what is already there. */
.dataTables_scrollHead table.dataTable,
.dataTables_scrollBody table.dataTable,
.dataTables_scrollFoot table.dataTable {
  table-layout: fixed;
}

/* Columns are narrow now that they all share one screen width, so let long
   values break and wrap. Truncating them would hide data outright, and a
   clipped "Ma... Clo... Ltd." is worse than two wrapped lines. */
.dataTables_scrollBody table.dataTable td {
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* Headings stay on one line; table-colresize.js sizes each column to fit its
   label, so wrapping here would only ever be a sign the column is too narrow. */
.dataTables_scroll table.dataTable thead th {
  white-space: nowrap;
}

/* DataTables absolutely positions the sort arrows against the cell's right edge
   and reserves 30px of padding to clear them. With centred headings that strands
   the icon far from the label it belongs to, so let it flow inline directly
   after the text and give the padding back. */
table.dataTable thead .sorting::after,
table.dataTable thead .sorting_asc::after,
table.dataTable thead .sorting_desc::after,
table.dataTable thead .sorting_asc_disabled::after,
table.dataTable thead .sorting_desc_disabled::after {
  position: static;
  display: inline-block;
  bottom: auto;
  right: auto;
  margin-left: 5px;
  vertical-align: middle;
}

/* Must mirror DataTables' own "thead > tr > th.sorting" shape: a shorter
   selector loses on specificity no matter which file loads last. */
table.dataTable thead > tr > th.sorting,
table.dataTable thead > tr > th.sorting_asc,
table.dataTable thead > tr > th.sorting_desc,
table.dataTable thead > tr > td.sorting,
table.dataTable thead > tr > td.sorting_asc,
table.dataTable thead > tr > td.sorting_desc {
  padding-right: 8px;
}

/* One sort glyph for every state: the neutral up/down arrows (\e150) that the
   unsorted state used, shown at the brighter 0.5 opacity the sorted state used.
   DataTables otherwise dims unsorted columns to 0.2, which is almost invisible
   against this dark header, and swaps in a single-direction arrow once sorted. */
table.dataTable thead .sorting::after,
table.dataTable thead .sorting_asc::after,
table.dataTable thead .sorting_desc::after,
table.dataTable thead .sorting_asc_disabled::after,
table.dataTable thead .sorting_desc_disabled::after {
  content: "\e150";
  opacity: 0.5;
}

/* Grab handle for table-colresize.js. It sits on the cell's right edge and is
   deliberately wider than it looks so it is easy to hit. */
.sb-col-resizer {
  position: absolute;
  top: 0;
  right: -3px;
  width: 7px;
  height: 100%;
  cursor: col-resize;
  user-select: none;
  z-index: 2;
}

/* The divider is always drawn so the grab point is visible without hunting for
   it, and lights up while hovered or dragged. */
.sb-col-resizer::after {
  content: "";
  position: absolute;
  top: 0;
  left: 3px;
  width: 1px;
  height: 100%;
  background: rgba(148, 163, 184, 0.35);
  transition: background 0.15s ease;
}

.sb-col-resizer:hover::after,
body.sb-col-resizing .sb-col-resizer::after {
  background: #38bdf8;
  width: 2px;
}

/* The first column carries a second handle on its leading edge so the table
   can be resized from its start as well as between columns. It sits fully
   inside the cell rather than straddling the edge like the others: there is
   no neighbouring column to overlap into, and the 3px overhang would be
   clipped by the scroll container. */
.sb-col-resizer.sb-col-resizer--start {
  left: 0;
  right: auto;
}

.sb-col-resizer.sb-col-resizer--start::after {
  left: 0;
}

/* Keep the cursor consistent while a drag is in flight. */
body.sb-col-resizing,
body.sb-col-resizing * {
  cursor: col-resize !important;
  user-select: none !important;
}

/* daisyUI's default button is 3rem (48px) tall, which dwarfs this app's 24px
   toolbars and makes modal footers look oversized. Buttons that opt into an
   explicit size (-xs/-sm/-md/-lg) keep whatever they asked for. */
.tw-dw-btn:not(.tw-dw-btn-xs):not(.tw-dw-btn-sm):not(.tw-dw-btn-md):not(.tw-dw-btn-lg) {
  height: 2rem;
  min-height: 2rem;
  padding-left: .75rem;
  padding-right: .75rem;
}

/* app.css paints this pricing table's headers #5cb85c with white text, which
   is 2.7:1 and reads as a light-theme strip inside the dark form. Match the
   other table headers instead. */
.add-product-price-table > thead > tr > th,
.add-product-price-table > tbody > tr > th,
.add-product-price-table th {
  background-color: var(--sb-surface-raised) !important;
  color: var(--sb-text) !important;
  border-color: var(--sb-border-strong) !important;
}

/* When every column is sb-col-fit, the table must be allowed to shrink-wrap,
   otherwise Bootstrap's .table { width: 100% } keeps it full-width and the
   columns just split the surplus between them. Pairs with the auto margins
   above, so a narrow table ends up centred in its card. */
table.sb-table-fit {
  width: auto !important;
}

/* autoWidth writes an inline pixel width onto every th; clear it so each
   column falls back to its content, and nowrap keeps values on one line. */
table.sb-table-fit > thead > tr > th,
table.sb-table-fit > tbody > tr > td,
table.sb-table-fit > tfoot > tr > td {
  width: auto !important;
  white-space: nowrap;
}

/* AdminLTE sizes the stat-card figure at 38px (vendor.css .small-box h3),
   which dwarfs its own label and the cards around it. Used by 5 views only
   (walk-ins, restaurant orders, suspended sales, staff availability) - the
   dashboard uses its own Tailwind cards and is unaffected. */
.small-box h3,
.small-box .inner h3 {
  font-size: 26px;
  font-weight: 700;
  line-height: 1.25;
  margin-bottom: 4px;
}

/* Bootstrap gives every <label> margin-bottom:5px. Inside an input-group addon
   that pushes the checkbox row upwards - 8px of space above it but 12px below
   in a 34px cell - and the box itself sits on the text baseline rather than
   centred against it. Seen on Business Settings > Custom Labels
   ("Is required" / "Is default for contact"). */
.content .input-group-addon label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 0;
  /* Fill the addon's content box (34px cell - 2x6px padding) so the row is
     centred by the flex box rather than by inline baseline metrics, which
     left it 2px high. */
  height: 22px;
  line-height: 22px;
  vertical-align: middle;
}

.content .input-group-addon label + label {
  margin-left: 12px;
}

.content .input-group-addon label > input[type="checkbox"],
.content .input-group-addon label > input[type="radio"] {
  margin: 0;
  vertical-align: middle;
}

/* Light hover fills left over from the light theme: the Filters bar carries
   hover:tw-bg-gray-50 (#f9fafb), so hovering it turns the strip near-white
   while the label stays near-white and the text disappears. Nine call sites
   across the views use one of these. */
.content .hover\:tw-bg-gray-50:hover,
.content .hover\:tw-bg-gray-100:hover,
.content .hover\:tw-bg-gray-200:hover,
.content .hover\:tw-bg-slate-100:hover,
.content .hover\:tw-bg-slate-200:hover {
  background-color: rgba(56, 189, 248, .08) !important;
}

/* A <select> or <textarea> without .form-control keeps the browser's default
   widget: a #3b3b3b fill, no border and no padding, which reads as broken next
   to the themed inputs beside it. Seen on Business Settings > Custom Labels
   ("Field Type" and the dropdown-values box). */
.content select:not(.form-control):not(.select2-hidden-accessible),
.content textarea:not(.form-control) {
  background-color: #0d1726;
  color: var(--sb-text);
  border: 1px solid var(--sb-border-strong);
  border-radius: 6px;
  padding: 5px 8px;
  font-size: 14px;
  max-width: 100%;
}

/* Inside an input-group addon it should read as part of that addon rather than
   as a second boxed field sitting inside the first. */
.content .input-group-addon > select:not(.form-control) {
  background-color: transparent;
  border: 0;
  border-radius: 0;
  padding: 0 4px 0 0;
  height: auto;
  cursor: pointer;
}

/* The open dropdown list is drawn by the browser using the select's own
   colours. A transparent select with light text therefore gives light text on
   the popup's light default, so the options are unreadable once opened. Give
   every option an explicit pair. */
.content select option,
.content select optgroup {
  background-color: #101827;
  color: var(--sb-text);
}

/* DataTables copies a column's className onto its footer cell, so a footer td
   written as class="text-left" ends up with both classes. They have equal
   specificity and vendor.css declares .text-center last, so the markup's own
   intent loses. Let an explicit text-left in a footer win. */
table tfoot td.text-left,
table tfoot th.text-left {
  text-align: left !important;
}

/* The "Total:" label in a footer row reads best hugging the first figure it
   sums, rather than centred in a wide colspan or pushed to the far left.
   Targeted by the <strong> it is always wrapped in rather than by position,
   because one view puts an empty <td> before it. !important because the
   column's own className (e.g. text-left on the Contact column) lands on the
   footer cell too. Applies to all 42 views that use .footer-total. */
tr.footer-total > td:has(> strong),
tr.footer-total > th:has(> strong) {
  text-align: right !important;
  vertical-align: middle !important;
}

/* The report summary lines ("Sale - Purchase: RM ...", "Due amount: RM ...")
   are marked up as <h3 class="text-muted">, so they render at 24px - larger
   than the page title's own weight class and out of scale with the cards they
   sit in. Used this way in purchase_sell, sales_representative and tax_report.
   Scoped to .text-muted so genuine <h3> section headings keep their size. */
.content h3.text-muted {
  font-size: 17px;
  font-weight: 600;
  line-height: 1.5;
  margin-top: 6px;
  margin-bottom: 6px;
}

.content h3.text-muted > span {
  font-size: inherit;
  font-weight: 700;
}

/* Bootstrap paints nested tables white via `.table .table { background:#fff }`.
   The Import Sales "Importable fields" table is nested inside the instructions
   table, so it inherited the theme's near-white text on a white fill: 1.11:1,
   effectively invisible. Scoped to nested tables only. */
.content .table .table,
.content .table .table > thead > tr > th,
.content .table .table > tbody > tr > td,
.content .table .table > tbody > tr > th {
  background-color: var(--sb-surface) !important;
  color: var(--sb-text) !important;
  border-color: var(--sb-border) !important;
}

.content .table .table > thead > tr > th {
  background-color: var(--sb-surface-raised) !important;
}

/* daisyUI already gives each solid colour button a readable foreground of its
   own (black on warning/info/success/error). 197 call sites across 155 files
   add tw-text-white on top, which drops "Deactivate Selected" to 1.66:1 on the
   amber warning fill. Restore a dark foreground on the solid light variants;
   measured ratios against #0b1422 in the comments. The transparent variants
   (outline/ghost/link) sit on the dark page, so they keep white, and
   tw-dw-btn-neutral is dark enough that white is correct there too. */
.tw-dw-btn.tw-text-white.tw-dw-btn-warning:not(.tw-dw-btn-outline):not(.tw-dw-btn-ghost):not(.tw-dw-btn-link),   /* 11.09:1 */
.tw-dw-btn.tw-text-white.tw-dw-btn-accent:not(.tw-dw-btn-outline):not(.tw-dw-btn-ghost):not(.tw-dw-btn-link),    /*  9.16:1 */
.tw-dw-btn.tw-text-white.tw-dw-btn-info:not(.tw-dw-btn-outline):not(.tw-dw-btn-ghost):not(.tw-dw-btn-link),      /*  7.96:1 */
.tw-dw-btn.tw-text-white.tw-dw-btn-secondary:not(.tw-dw-btn-outline):not(.tw-dw-btn-ghost):not(.tw-dw-btn-link), /*  6.56:1 */
.tw-dw-btn.tw-text-white.tw-dw-btn-error:not(.tw-dw-btn-outline):not(.tw-dw-btn-ghost):not(.tw-dw-btn-link) {    /*  6.00:1 */
  color: #0b1422 !important;
}

/* AdminLTE status labels (payment status, transaction status, shipping status)
   paint white text on light pastel fills: "Paid" on bg-light-green measures
   1.68:1, which is effectively invisible. Give each fill whichever foreground
   clears WCAG AA; measured ratios in the comments. Scoped to .label/.badge so
   the same utilities keep working as panel backgrounds elsewhere. */
.label.bg-light-green, .badge.bg-light-green,   /* 11.00:1 */
.label.bg-lime, .badge.bg-lime,                 /* 13.66:1 */
.label.bg-yellow, .badge.bg-yellow,             /*  9.95:1 */
.label.bg-aqua, .badge.bg-aqua,                 /*  9.67:1 */
.label.bg-teal, .badge.bg-teal,                 /*  9.39:1 */
.label.bg-green, .badge.bg-green,               /*  9.06:1 */
.label.bg-orange, .badge.bg-orange,             /*  7.58:1 */
.label.bg-olive, .badge.bg-olive,               /*  5.27:1 */
.label.bg-red, .badge.bg-red,                   /*  4.89:1 */
.label.bg-fuchsia, .badge.bg-fuchsia {          /*  4.87:1 */
  color: #0b1422 !important;
  font-weight: 700;
}

.label.bg-black, .badge.bg-black,               /* 18.88:1 */
.label.bg-navy, .badge.bg-navy,                 /* 16.56:1 */
.label.bg-purple, .badge.bg-purple,             /*  5.84:1 */
.label.bg-blue, .badge.bg-blue,                 /*  5.08:1 */
.label.bg-maroon, .badge.bg-maroon {            /*  4.95:1 */
  color: #ffffff !important;
  font-weight: 700;
}

/* .bg-gray is the odd one out, so it gets its own rule rather than a seat in
   either list above. AdminLTE fills it pastel #d2d6de, which is why it used
   to sit with the dark-ink badges - but ".content .bg-gray" earlier in this
   file repaints every grey surface inside the content area to #1b2b43, and
   that caught these pills too, leaving #0b1422 ink on a dark fill at 1.30:1
   ("Login not allowed" on /users was effectively invisible). Pinning both
   halves here makes the pill read the same wherever it lands, and matches
   the light sheet's fill. White on #475569 is 7.4:1. */
.label.bg-gray, .badge.bg-gray {
  background-color: #475569 !important;
  color: #ffffff !important;
  font-weight: 700;
}

/* 10.5px is small for a status pill; nudge it up without changing row height. */
table.dataTable .label,
table.dataTable .badge {
  font-size: 11.5px;
  letter-spacing: .2px;
  padding: 3px 8px;
}

/* Action columns hold a fixed button pair, but auto table-layout spreads the
   table's full width across every column and leaves them about twice as wide
   as their content. width:1% is the shrink-to-fit idiom: under auto layout the
   browser falls back to the minimum content width, and nowrap keeps the
   buttons on one line. !important is needed because DataTables' autoWidth
   writes inline widths onto the header cells. Applied via a column className
   so it follows the column whatever its index. */
table.dataTable > thead > tr > th.sb-col-fit,
table.dataTable > tbody > tr > td.sb-col-fit {
  width: 1% !important;
  white-space: nowrap;
}

/* With autoWidth on, DataTables sizes a non-scrolling table to its content and
   leaves it flush left, so a narrow table sits against one edge of a wide card.
   Centre it in the leftover space. Scrolling tables are nested inside
   .dataTables_scrollBody rather than being a direct child, so they keep their
   head/body/foot panes aligned. */
.dataTables_wrapper > table.dataTable {
  margin-left: auto;
  margin-right: auto;
  /* autoWidth can bake an inline pixel width wider than the container (the
     categories table measured 1396px inside 1238px), which clips the last
     column. !important is required because vendor.css sets
     table.dataTable { max-width: none !important }. */
  max-width: 100% !important;
}

/* tw-dw-btn-lg is 4rem tall with 18px text, roughly double every other action
   button in the app. It is used only on form submit rows (26 views: product,
   purchase, sell, expense, role, labels, settings...) and never on POS touch
   targets, so bring the size down centrally rather than page by page. */
.tw-dw-btn.tw-dw-btn-lg {
  height: 2.25rem !important;
  min-height: 2.25rem !important;
  font-size: 14px !important;
  padding-left: 1.125rem !important;
  padding-right: 1.125rem !important;
}

/* Product brochure and variation images render as raw OS file pickers. Give
   them the same control surface as the rest of the form. */
input[type="file"]:not(.upload-element) {
  color: var(--sb-muted);
  font-size: 13px;
}

input[type="file"]:not(.upload-element)::file-selector-button {
  margin-right: 10px;
  padding: 5px 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--sb-text);
  background: var(--sb-surface-raised);
  border: 1px solid var(--sb-border-strong);
  border-radius: 6px;
  cursor: pointer;
  transition: background .15s ease;
}

input[type="file"]:not(.upload-element)::file-selector-button:hover {
  background: var(--sb-surface-hover);
}

/* Toolbar "Add" actions are anchors, so the theme-wide a:not(.btn) rule would
   repaint their label with the link colour instead of white. */
a.tw-bg-gradient-to-r.tw-from-indigo-500,
a.tw-bg-gradient-to-r.tw-from-indigo-500:hover,
a.tw-bg-gradient-to-r.tw-from-indigo-500:focus,
button.tw-bg-gradient-to-r.tw-from-indigo-500,
button.tw-bg-gradient-to-r.tw-from-indigo-500:hover,
button.tw-bg-gradient-to-r.tw-from-indigo-500:focus {
  color: #fff !important;
}

/* FullCalendar ships light-mode surfaces (#fafafa header, #fcf8e3 today cell).
   Against the theme's near-white text those render white-on-white, hiding the
   weekday names and today's date number. */
.fc-unthemed th.fc-day-header,
.fc-unthemed th.fc-widget-header {
  background: var(--sb-surface) !important;
  border-color: var(--sb-border) !important;
}

.fc-unthemed .fc-today {
  background: rgba(56, 189, 248, .12) !important;
}

/* 0.3 is tuned for dark text on white; on a dark surface it disappears. */
.fc-unthemed .fc-other-month {
  opacity: .45 !important;
}

@media print {
  .side-bar,
  .pos-form-actions,
  .main-header,
  .pos-header {
    display: none !important;
  }
}

/* Column Visibility dropdown -------------------------------------------------
   Buttons renders each column as <li class="dt-button ... active"><a>, and
   Bootstrap's .dropdown-menu > .active > a fills that anchor with #337ab7
   while the theme paints its label var(--sb-muted): #97a9c1 on #337ab7 is
   1.90:1, i.e. unreadable. Every column is visible by default, so every row
   carries .active and the whole menu rendered as one blue block.

   Replaced with a plain menu that states on/off by weight rather than by a
   saturated fill: a shown column gets full-strength text, a raised row and an
   accent bar down its left edge; a hidden one is simply muted. Both read
   correctly in either theme because every value is a token.
   --------------------------------------------------------------------------- */
.dt-button-collection > .dt-button > a,
.dt-button-collection > .dt-button > button,
.dt-button-collection > li > a {
  display: block;
  padding: 7px 14px !important;
  background: transparent !important;
  background-image: none !important;
  /* Column currently hidden. */
  color: var(--sb-muted) !important;
  border: 0 !important;
  cursor: pointer;
}

/* Column currently shown. */
.dt-button-collection > .dt-button.active > a,
.dt-button-collection > .dt-button.active > button {
  background: var(--sb-surface-hover) !important;
  color: var(--sb-text) !important;
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--sb-accent) !important;
}

.dt-button-collection > .dt-button > a:hover,
.dt-button-collection > .dt-button > a:focus,
.dt-button-collection > .dt-button.active > a:hover,
.dt-button-collection > .dt-button.active > a:focus {
  background: var(--sb-surface-raised) !important;
  color: var(--sb-text) !important;
}

/* The panel itself: AdminLTE gives ul.dt-button-collection a #00c0ef fill. */
.dt-button-collection {
  padding: 4px 0 !important;
  background: var(--sb-surface) !important;
  border: 1px solid var(--sb-border) !important;
  border-radius: 8px !important;
  overflow: hidden;
}

/* Active sidebar item's icon -------------------------------------------------
   The active pill keeps its pale #e0f2fe background in both themes, and its
   label is #075985 in both. The icon does not follow: an earlier rule
   re-points #side-bar a.theme-sidebar-active svg to var(--sb-accent), which
   is #38bdf8 in dark - 1.87:1 against that pale pill, so the glyph all but
   vanishes while its label stays perfectly readable.

   Letting the icon inherit the item's own colour puts it at 6.59:1 and keeps
   icon and label matching. Applies to every active menu item, not just
   Woocommerce, since they all share this treatment.

   `color` has to be inherited as well as `stroke` set: the icon's own colour
   is what currentColor resolves against, and an earlier rule sets that colour
   to the accent, so stroke:currentColor alone still came out #38bdf8. */
#side-bar a.theme-sidebar-active svg,
#side-bar a.theme-sidebar-active i {
  color: inherit !important;
  stroke: currentColor !important;
}

/* Woocommerce tab strip ------------------------------------------------------
   The first tab is the module's brand label rather than a real tab, so it
   carries no active state and must not light up on hover. It stays a link so
   the Sync Log and API Settings screens have a way back. */
/* Three separate things were drawing the hover box, which is why pinning one
   property at a time kept missing: vendor.css gives every li a 3px top
   border, Bootstrap paints a bordered tab panel on a:hover, and the theme's
   own rule swaps the label colour. Rather than chase them, every visual
   property is held identical across all interaction states.

   The background is transparent rather than var(--sb-surface) so the label
   blends into the strip instead of sitting on a panel of its own. */
.nav-tabs-custom > .nav-tabs > li.wc-tab-brand,
.nav-tabs-custom > .nav-tabs > li.wc-tab-brand:hover,
.nav-tabs-custom > .nav-tabs > li.wc-tab-brand:focus-within {
  border-top-color: transparent !important;
  box-shadow: none !important;
}

.nav-tabs-custom > .nav-tabs > li.wc-tab-brand > a,
.nav-tabs-custom > .nav-tabs > li.wc-tab-brand > a:link,
.nav-tabs-custom > .nav-tabs > li.wc-tab-brand > a:visited,
.nav-tabs-custom > .nav-tabs > li.wc-tab-brand > a:hover,
.nav-tabs-custom > .nav-tabs > li.wc-tab-brand > a:focus,
.nav-tabs-custom > .nav-tabs > li.wc-tab-brand > a:active {
  background: transparent !important;
  background-color: transparent !important;
  background-image: none !important;
  border: 1px solid transparent !important;
  box-shadow: none !important;
  outline: none !important;
  color: var(--sb-muted) !important;
  text-decoration: none !important;
  transition: none !important;
  transform: none !important;
  filter: none !important;
  opacity: 1 !important;
}

.nav-tabs-custom > .nav-tabs > li.wc-tab-brand > a i,
.nav-tabs-custom > .nav-tabs > li.wc-tab-brand > a:hover i {
  color: inherit !important;
}

/* Woocommerce API settings ---------------------------------------------------
   Bootstrap's .nav-pills paints the active pill #337ab7 and relies on its own
   white label, but the theme's link rule repaints that label var(--sb-accent-
   strong) - 1.66:1 in light. The inactive pills had no fill at all, so in dark
   the sky-300 link colour sat on the card at 1.67:1. The pane text is also
   hard-coded #0f172a by the widget, which is unreadable on the dark card.

   Everything below is token-based except the active pill, which is pinned to
   #075985: white on it is 7.57:1, and a token would have resolved to the
   lighter #0284c7 in dark mode and dropped to about 3.9:1. */
/* AdminLTE gives each stacked nav item a #f4f4f4 bottom border. It is
   invisible on a white page but shows as a white rule across the gaps
   between the pills on the dark card. The pills carry their own borders, so
   the separator is simply removed. */
.wc-settings .wc-settings-nav > li {
  border: 0 !important;
}

.wc-settings .wc-settings-nav > li > a {
  background: var(--sb-surface-raised) !important;
  color: var(--sb-text) !important;
  border: 1px solid var(--sb-border) !important;
  border-radius: 8px !important;
  margin-bottom: 6px;
  font-weight: 600;
}

.wc-settings .wc-settings-nav > li > a:hover,
.wc-settings .wc-settings-nav > li > a:focus {
  background: var(--sb-surface-hover) !important;
  color: var(--sb-text) !important;
}

.wc-settings .wc-settings-nav > li.active > a,
.wc-settings .wc-settings-nav > li.active > a:hover,
.wc-settings .wc-settings-nav > li.active > a:focus {
  background: #075985 !important;
  border-color: #075985 !important;
  color: #ffffff !important;
}

/* Pane copy and field labels: the widget hard-codes a dark ink that only
   works on a white card. */
.wc-settings .tab-pane,
.wc-settings .tab-pane p,
.wc-settings .tab-pane label,
.wc-settings .tab-pane li {
  color: var(--sb-text) !important;
}

.wc-settings .tab-pane code {
  background: var(--sb-surface-raised) !important;
  color: var(--sb-text) !important;
  border: 1px solid var(--sb-border) !important;
  border-radius: 4px;
  padding: 1px 5px;
}

/* Woocommerce tab strip ------------------------------------------------------
   The active tab (Sync Log / API Settings) needs to read as selected in both
   themes, and the rule under the strip has to stay visible on a dark card as
   well as a light one. Scoped to .wc-tabs so the tab strips on other pages
   keep their existing treatment.

   The underline is an inset box-shadow rather than a border so it does not
   shift the tab by a pixel when it becomes active. */
.wc-tabs > .nav-tabs {
  border-bottom: 1px solid var(--sb-border-strong) !important;
}

.wc-tabs > .nav-tabs > li.active > a,
.wc-tabs > .nav-tabs > li.active > a:hover,
.wc-tabs > .nav-tabs > li.active > a:focus {
  background: var(--sb-surface-hover) !important;
  color: var(--sb-text) !important;
  border-color: transparent !important;
  box-shadow: inset 0 -3px 0 var(--sb-accent) !important;
  font-weight: 600;
}

/* vendor.css turns the li's 3px top border blue on .active; the indicator
   here is the underline, so that one is cleared.

   margin-bottom is vendor's -2px, which hangs every tab two pixels below the
   ul and paints over its bottom border - the rule appeared chopped into
   segments between the tabs. Zeroing it lets the line run unbroken beneath
   them, with the active tab's accent underline sitting just above it. */
.wc-tabs > .nav-tabs > li,
.wc-tabs > .nav-tabs > li.active {
  border-top-color: transparent !important;
  margin-bottom: 0 !important;
}

/* Login / auth screens -------------------------------------------------------
   auth2.blade.php was written dark-first: the controls above the card are
   hardcoded tw-text-white / tw-border-white, which is invisible on the light
   page background. Everything here is token-based so both themes work, and
   it is scoped to .sb-auth so no authenticated screen is affected. */

/* Gradient-clipped text ("Forgot Your Password?"). Solid, accessible colour
   rather than the gradient, which is too low-contrast at this size. */
a.tw-bg-gradient-to-r.tw-bg-clip-text {
  color: #93c5fd !important;
  -webkit-text-fill-color: #93c5fd !important;
}

/* Top-right controls: Register pill, Sign in, language, theme toggle.
   `summary` is in the list because the language picker's trigger is a
   <details>/<summary>, not a link - it was hardcoded white and sat at
   1.12:1 on the light page. */
.sb-auth-actions a,
.sb-auth-actions button,
.sb-auth-actions summary {
  color: var(--sb-text) !important;
}

/* Register sits next to the theme toggle and is styled to match it exactly:
   same surface, border, radius, hover and 44px height. It used to be a
   transparent 40px pill, so the pair read as two unrelated controls - one
   filled circle, one empty outline, 4px apart in height. */
.sb-auth-actions .sb-auth-pill {
  height: 44px;
  background: var(--sb-surface) !important;
  border-color: var(--sb-border-strong) !important;
  border-radius: 9999px;
  transition: background-color .2s ease, border-color .2s ease;
}

.sb-auth-actions .sb-auth-pill:hover {
  background: var(--sb-surface-hover) !important;
  border-color: var(--sb-accent) !important;
}

/* The label, matched to the toggle's icon colour. The light sheet's blanket
   link rule is (0,4,2) and was repainting it --sb-accent-strong (#075985),
   so the same :not() chain is repeated here to reach (0,5,1) and win. */
.sb-auth-actions .sb-auth-pill a:not(.btn):not(.tw-dw-btn):not(.tw-bg-gradient-to-r) {
  color: var(--sb-text) !important;
}

/* Theme toggle on the login page. The authenticated header gives its button a
   translucent-on-dark treatment that disappears on a light page, so the auth
   copy gets a bordered surface instead. 44px square meets the minimum touch
   target. */
.sb-auth-actions .sb-auth-theme-toggle {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--sb-border-strong);
  border-radius: 9999px;
  background: var(--sb-surface);
  color: var(--sb-text);
  transition: background-color .2s ease, border-color .2s ease;
}

.sb-auth-actions .sb-auth-theme-toggle:hover,
.sb-auth-actions .sb-auth-theme-toggle:focus-visible {
  background: var(--sb-surface-hover);
  border-color: var(--sb-accent);
}

/* Registration wizard steps --------------------------------------------------
   jQuery Steps renders each step as <li><a>, and relies on its own white
   label over a coloured chip. The theme's link rule repaints every anchor,
   so in light mode the labels came out #075985 on a #2184be chip - 1.84:1,
   effectively unreadable ("1. Business", "2. Business Settings", "3. Owner").

   The chips are restyled here instead of just forcing white back: white on
   the stock #2184be is only ~3.4:1, still under AA. The current step uses a
   fixed #075985 (white on it is 7.56:1 in both themes - a token would
   resolve to the lighter #0284c7 in dark and fall to ~3.9:1); the other
   steps become quiet surfaces rather than pale blue. */
.wizard .steps li > a {
  background: var(--sb-surface-raised) !important;
  color: var(--sb-muted) !important;
  border-radius: 10px;
}

.wizard .steps li.done > a {
  background: var(--sb-surface-hover) !important;
  color: var(--sb-text) !important;
}

/* No font-weight bump: the other two steps stay at their normal weight, so
   bolding only the current one made the row look mismatched. The filled
   chip is already the "you are here" signal. */
.wizard .steps li.current > a {
  background: #075985 !important;
  color: #ffffff !important;
}

.wizard .steps li > a .number {
  color: inherit !important;
  opacity: .8;
}

/* Disabled "Previous" was #aaa on #eee (2.00:1). Disabled controls are
   exempt from the contrast minimum, but that is too faint to read at all;
   --sb-faint keeps it clearly inactive while staying legible. */
.wizard .actions a.tw-dw-btn[disabled],
.wizard .actions .disabled > a {
  background: var(--sb-surface-raised) !important;
  color: var(--sb-faint) !important;
}

/* jQuery Steps hardcodes a white background on its content panel. The card
   around it themes correctly, so in dark mode the panel stayed white while
   the labels inside went light - "Business details:", "Business Name:*" and
   the rest sat at about 1.1:1. Transparent lets the card show through, which
   is correct in both themes (the card is white in light anyway). */
.wizard > .content,
.wizard > .content > .body {
  background: transparent !important;
}

/* Wizard steps on hover, dark side. Same idea as the light sheet: the
   surface shifts, the label colour holds. */
.wizard .steps li > a:hover,
.wizard .steps li > a:focus {
  background: var(--sb-surface-hover) !important;
  color: var(--sb-text) !important;
}

.wizard .steps li.current > a:hover,
.wizard .steps li.current > a:focus {
  background: #0a6ea3 !important;
  color: #ffffff !important;
}

/* Registration wizard actions ------------------------------------------------
   Next/Register were daisyUI's stock primary - oklch(0.4912 0.3096 275.75),
   an electric violet at chroma 0.31 that belongs to no other control in this
   app. They now use the same indigo->blue gradient as the Login button and
   the "Add" buttons, so the wizard's CTA matches every other primary action.
   White on #4f46e5 is 6.3:1 and on #1d4ed8 is 6.7:1, so the pair is safe on
   either theme's card.

   Semibold, and the label is centred on both axes. jQuery Steps ships these
   as plain anchors, so the label sat on the text baseline rather than in the
   middle of the pill; inline-flex with both centring axes and line-height 1
   puts it dead centre whatever the button's height ends up being. */
.wizard .actions a.tw-dw-btn {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  text-align: center !important;
  line-height: 1 !important;
  font-weight: 600 !important;
  border-radius: 8px !important;
  padding-left: 18px !important;
  padding-right: 18px !important;
}

.wizard .actions a.tw-dw-btn-primary {
  background-color: transparent !important;
  background-image: linear-gradient(to right, #4f46e5, #1d4ed8) !important;
  border-color: transparent !important;
  color: #ffffff !important;
}

.wizard .actions a.tw-dw-btn-primary:hover,
.wizard .actions a.tw-dw-btn-primary:focus {
  background-image: linear-gradient(to right, #4338ca, #1e40af) !important;
}

/* Previous, enabled: a quiet secondary next to that CTA. */
.wizard .actions li:not(.disabled) > a.tw-dw-btn:not(.tw-dw-btn-primary) {
  background: var(--sb-surface-raised) !important;
  color: var(--sb-text) !important;
  border: 1px solid var(--sb-border-strong) !important;
}

.wizard .actions li:not(.disabled) > a.tw-dw-btn:not(.tw-dw-btn-primary):hover {
  background: var(--sb-surface-hover) !important;
  border-color: var(--sb-accent) !important;
}

/* The Total Walk-In KPI is an <a> into /walk-ins, matching the test install.
   Every child (__icon, __label, __value, __hint) sets its own colour in both
   themes, so nothing inherits the theme's link colour and no override is
   needed for that - these rules only kill the underline bootstrap adds on
   hover (text-decoration inherits, so it would underline the whole tile) and
   give the tile a hover affordance so it reads as clickable. */
a.sb-dashboard-kpi {
  transition: transform .15s ease;
}

a.sb-dashboard-kpi,
a.sb-dashboard-kpi:hover,
a.sb-dashboard-kpi:focus {
  text-decoration: none !important;
}

a.sb-dashboard-kpi:hover {
  transform: translateY(-1px);
}

/* The POS "+ WALK-IN" button shipped as btn-success, painting it #047857 -
   an emerald that appears nowhere else in this app. It now uses the same
   indigo->blue primary gradient as the Login button, the Add buttons and
   the registration wizard's Next. */
#walk-in-pos-controls #capture_walk_in {
  background-color: transparent !important;
  background-image: linear-gradient(to right, #4f46e5, #1d4ed8) !important;
  border-color: transparent !important;
  color: #ffffff !important;
}

#walk-in-pos-controls #capture_walk_in:hover,
#walk-in-pos-controls #capture_walk_in:focus {
  background-image: linear-gradient(to right, #4338ca, #1e40af) !important;
}

/* Disabled POS footer actions. Card, Cash and Multiple Pay are disabled
   until the cart has a line, but they kept their saturated fills at
   partial strength, so they read as low-contrast enabled buttons rather
   than as unavailable ones. */
body.lockscreen .pos-form-actions button:disabled,
body.lockscreen .pos-form-actions button[disabled] {
  opacity: .45 !important;
  filter: grayscale(.4);
  cursor: not-allowed !important;
  box-shadow: none !important;
}

/* Slim scrollbar for the notifications dropdown. Colour lives here because
   saverbro-layout.css is colour-free; the track stays transparent so the
   panel's own surface shows through in both themes. */
.notifications-menu > .dropdown-menu::-webkit-scrollbar-track {
  background: transparent;
}

.notifications-menu > .dropdown-menu::-webkit-scrollbar-thumb {
  background: var(--sb-border-strong);
  border-radius: 3px;
}

.notifications-menu > .dropdown-menu::-webkit-scrollbar-thumb:hover {
  background: var(--sb-muted);
}

/* Solid success buttons ---------------------------------------------------
   daisyUI's success fill is oklch(0.648 0.15 160) - light enough that a white
   label lands near 2.3:1, which is why the rule above forces dark ink on the
   other solid colours. Green buttons elsewhere in the app (POS Suspend and
   Credit Sale) are white on the darker emerald, so matching that fill here
   gives the white label the rest of the UI uses and clears AA at the same
   time: 5.49:1 at #047857 rising to 7.69:1 at #065f46. */
.tw-dw-btn.tw-dw-btn-success:not(.tw-dw-btn-outline):not(.tw-dw-btn-ghost):not(.tw-dw-btn-link) {
  background-color: transparent !important;
  background-image: linear-gradient(135deg, #047857, #065f46) !important;
  border-color: transparent !important;
  color: #ffffff !important;
}

.tw-dw-btn.tw-dw-btn-success:not(.tw-dw-btn-outline):not(.tw-dw-btn-ghost):not(.tw-dw-btn-link):hover,
.tw-dw-btn.tw-dw-btn-success:not(.tw-dw-btn-outline):not(.tw-dw-btn-ghost):not(.tw-dw-btn-link):focus {
  background-image: linear-gradient(135deg, #065f46, #064e3b) !important;
  color: #ffffff !important;
}

/* Circular loader colours -------------------------------------------------
   Structure lives in saverbro-layout.css. This sheet loads in both themes and
   the tokens are redefined per theme, so one block covers dark and light:
   the track picks up --sb-border-strong (#354966 dark / #cbd5e1 light) and the
   arc --sb-accent (#38bdf8 / #0369a1), both of which already clear AA against
   their own surface. */

.sb-loader-track {
  stroke: var(--sb-border-strong);
}

.sb-loader-arc {
  stroke: var(--sb-accent);
}

.sb-loader-label {
  color: var(--sb-muted);
}

/* The DataTables processing box is the loader's main home. The ring is the
   whole indicator now - no label, no card - so this strips the box back to
   nothing but a positioned, centred container for it. */
.dataTables_wrapper .dataTables_processing .sb-loader {
  justify-content: center;
}

.dataTables_wrapper .dataTables_processing {
  /* Transparent: the ring is the whole indicator, floating over the table
     rather than sitting on a panel. !important is needed on every line here,
     for two different reasons:

     - DataTables gives this element `class="dataTables_processing panel
       panel-default"`, and the .panel/.panel-default rules - vendor's and this
       sheet's own - set background, border and shadow, this sheet's with
       !important.
     - vendor.css targets it as `div.dataTables_wrapper div.dataTables_processing`,
       which is (0,2,2) against this selector's (0,2,0), so its `padding: 1em 0`
       wins on specificity. */
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  padding: 0 !important;
  /* DataTables' `dom` string puts the processing div (r) before the table (t),
     and the box ships with no stacking context of its own, so the rows painted
     over it and the loader sat hidden behind data on every reload. Lifting it
     here fixes that without touching layout. */
  z-index: 20;
}

/* Dashboard tile backdrop -------------------------------------------------
   home/index.blade.php lays a two-row grid behind the summary tiles: a
   .theme-header-bg gradient on top and a tw-bg-gray-100 block underneath.
   The tiles straddle the seam, so the strip behind them was split into two
   tones - the gradient (#080e19 -> #0d1d31) above and a flat #111d2e below.

   Flattening both to transparent lets the page's own background show through
   as one colour, which is what saverbro-light.css:109 already does for light
   mode - this brings dark into line rather than inventing a third treatment.

   Scoped to the backdrop's own children: .theme-header-bg is also on the
   command header and on the dashboard root, and both must keep their gradient.
   `.tw-absolute.tw-inset-0.tw-grid` matches only this backdrop.

   The #scrollable-container prefix is not decoration: the bottom half is held
   by `#scrollable-container .tw-bg-gray-100 { ... !important }`, and an ID puts
   that at (1,1,0). Without the id here this rule was (0,4,0) and lost. */
#scrollable-container .saverbro-dashboard .tw-absolute.tw-inset-0.tw-grid > * {
  background-image: none !important;
  background-color: transparent !important;
}

/* The dashboard wrapper carries .theme-header-bg, whose gradient sat behind
   both tile rows. Removing it lets the tiles sit on the page background, which
   is what saverbro-light.css:106 already does for light mode - so this brings
   dark into line rather than inventing a different treatment.

   Only the wrapper itself is cleared. .theme-header-bg is also on the command
   header card ("SAVERPOS Command Center"), which is a child of this element
   and keeps its own gradient - that panel is still wanted.

   The id is for specificity, not decoration: the gradient is declared as
   `.theme-header-bg, body .theme-header-bg { ... !important }` near the top of
   this sheet, so a class-only rule here would tie and lose on source order. */
#scrollable-container .saverbro-dashboard {
  background-image: none !important;
  background-color: transparent !important;
}
