/* ============================================================
   Arawali Agro Industries ERP — Main Stylesheet
   ============================================================ */

/* ─── CSS Variables ─────────────────────────────────────────────
   Colour tokens below are the DEFAULT theme (Amber). The active
   theme is chosen in Settings → Appearance and injected as an
   overriding :root block in the page <head> (see theme_css() in
   core/helpers.php and config/themes.php). Add new colours as
   tokens here, never as hex literals further down this file, or
   they will not follow the selected theme.
   ─────────────────────────────────────────────────────────────── */
:root {
  /* Brand */
  --color-primary:        #E16E1E;
  --color-primary-light:  #F0913F;
  --color-primary-dark:   #C25A12;
  --color-primary-darker: #A84A0E;
  --color-primary-rgb:    225, 110, 30;

  /* Headings & chrome */
  --color-secondary:      #2A2420;
  --color-heading:        #2A2420;
  --color-sidebar:        #1A1613;
  --color-sidebar-hover:  rgba(var(--color-primary-rgb), 0.12);

  /* Surfaces */
  --color-bg:             #F7F5F1;
  --color-bg-2:           #EFEBE4;
  --color-card:           #FFFFFF;
  --color-head-1:         #FAF8F4;
  --color-head-2:         #F3EEE7;

  /* Borders */
  --color-border:         #EAE3D8;
  --color-border-strong:  #E4D9C9;
  --color-border-soft:    #F0E9DF;

  /* Tables */
  --color-th-bg:          #F5F0E9;
  --color-th-bg-2:        #EFE9E0;
  --color-th-text:        #2A2420;
  --color-row-alt:        #FBF8F3;
  --color-row-hover:      #FDF1E7;

  /* Text */
  --color-text:           #1A202C;
  --color-text-muted:     #7A7168;

  /* Semantic — intentionally NOT themed: these encode meaning */
  --color-success:        #38A169;
  --color-danger:         #E53E3E;
  --color-warning:        #D69E2E;

  --sidebar-width:        92px;
  --topbar-height:        64px;
  --radius:               12px;
  --radius-sm:            8px;
  --shadow-sm:            0 1px 4px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
  --shadow:               0 4px 12px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.04);
  --shadow-lg:            0 10px 30px rgba(0,0,0,0.10), 0 4px 10px rgba(0,0,0,0.05);
  --transition:           all 0.25s ease;
}

/* ─── Reset & Base ──────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

body {
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  background: var(--color-bg);
  color: var(--color-text);
  margin: 0;
  opacity: 0;
  animation: fadeInBody 0.4s ease 0.05s forwards;
  font-size: 0.9375rem;
  line-height: 1.6;
}

a { text-decoration: none; color: inherit; }
img { max-width: 100%; }

/* ─── Animations ────────────────────────────────────────────── */
@keyframes fadeInBody {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0);    }
}

@keyframes fadeInLeft {
  from { opacity: 0; transform: translateX(-40px); }
  to   { opacity: 1; transform: translateX(0);     }
}

@keyframes fadeInRight {
  from { opacity: 0; transform: translateX(40px); }
  to   { opacity: 1; transform: translateX(0);    }
}

@keyframes float {
  0%, 100% { transform: translateY(0) rotate(0deg);    opacity: 0.15; }
  50%       { transform: translateY(-20px) rotate(5deg); opacity: 0.25; }
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.5; }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* ─── Layout ────────────────────────────────────────────────── */
.app-wrapper {
  display: flex;
  min-height: 100vh;
}

/* ─── Sidebar (compact icon rail) ───────────────────────────── */
.sidebar {
  width: var(--sidebar-width);
  min-height: 100vh;
  background: var(--color-sidebar);
  border-right: none;
  box-shadow: 4px 0 20px rgba(0,0,0,0.18);
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  transition: transform 0.3s ease;
  overflow: visible; /* allow flyout submenus to escape */
}

/* Logo area */
/* Height and border must match .topbar exactly, so the rule under the logo and
   the rule under the page title read as one continuous line across the app.
   Both are border-box, so an equal `height` puts both borders on the same row. */
.sidebar-header {
  height: var(--topbar-height);
  padding: 6px 0;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--color-card);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: 4px;
}

.sidebar-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-decoration: none;
}

.sidebar-brand img {
  max-height: 100%;   /* fits whatever height .sidebar-header is */
  width: auto;
  object-fit: contain;
  padding: 2px;
}

.sidebar-brand-text {
  display: none; /* hidden in compact mode, shown on mobile */
  color: var(--color-text);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.sidebar-brand-text span { color: var(--color-primary); }

/* Nav container */
.sidebar-nav {
  flex: 1;
  padding: 6px 0;
  overflow: visible;
}

/* Each nav group */
.snav-item {
  position: relative;
  margin: 2px 5px;
}

/* The clickable icon+label tile */
.snav-link {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 9px 4px 7px;
  border-radius: 8px;
  color: rgba(255,255,255,0.75);
  text-decoration: none;
  transition: background 0.18s ease, color 0.18s ease;
  gap: 3px;
  position: relative;
}

.snav-link:hover,
.snav-item:hover > .snav-link {
  background: rgba(var(--color-primary-rgb),0.14);
  color: #ffffff;
}

.snav-link.is-active {
  background: rgba(var(--color-primary-rgb),0.2);
  color: #ffffff;
}

.snav-icon {
  font-size: 1.2rem;
  line-height: 1;
}

.snav-label {
  font-size: 0.58rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-align: center;
  line-height: 1.2;
  white-space: nowrap;
}

/* Chevron arrow (hidden by default, shown in mobile expanded) */
.snav-arrow {
  display: none;
  font-size: 0.7rem;
  margin-left: auto;
  opacity: 0.4;
}

/* Active indicator dot */

/* ── Flyout submenu ──────────────────────────────────────────── */
.snav-fly {
  position: absolute;
  left: 100%;           /* flush against sidebar — no gap to cross */
  top: 0;
  min-width: 200px;
  background: #fff;
  border-radius: 0 10px 10px 0;
  box-shadow: 6px 4px 24px rgba(0,0,0,0.13), 0 2px 8px rgba(0,0,0,0.07);
  opacity: 0;
  visibility: hidden;
  transform: translateX(-6px);
  transition: opacity 0.14s ease, transform 0.14s ease, visibility 0.14s;
  z-index: 2000;
  pointer-events: none;
  /* Was overflow:hidden, which silently cut off the tail of a long menu.
     Cap to the viewport and scroll instead so every entry stays reachable. */
  overflow-x: hidden;
  overflow-y: auto;
  max-height: calc(100vh - 16px);
  padding: 4px 0;
}

/* JS adds .fly-open — replaces CSS :hover trigger */
.snav-item.fly-open .snav-fly {
  opacity: 1;
  visibility: visible;
  transform: translateX(0);
  pointer-events: auto;
}

/* Flyout anchored upward for bottom items */
.snav-fly-up {
  top: auto;
  bottom: 0;
}

/* 2-column wide flyout (e.g. Accounting) */
.snav-fly-wide {
  min-width: 400px;
  display: flex;
  flex-wrap: wrap;
}
.snav-fly-wide .snav-fly-item {
  width: 50%;
  box-sizing: border-box;
}

.snav-fly-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 16px;
  font-size: 0.855rem;
  color: var(--color-text);
  text-decoration: none;
  transition: background 0.13s ease, padding-left 0.13s ease, color 0.13s ease;
}

.snav-fly-item i {
  width: 15px;
  text-align: center;
  font-size: 0.88rem;
  flex-shrink: 0;
  color: var(--color-text-muted);
}

.snav-fly-item:hover {
  background: var(--color-bg);
  color: var(--color-primary);
  padding-left: 20px;
}

.snav-fly-item:hover i { color: var(--color-primary); }

.snav-fly-item.is-active {
  color: var(--color-primary);
  font-weight: 600;
  background: rgba(var(--color-primary-rgb),0.06);
}

.snav-fly-item.is-active i { color: var(--color-primary); }

.snav-fly-danger { color: var(--color-danger) !important; }
.snav-fly-danger i { color: var(--color-danger) !important; }
.snav-fly-danger:hover { background: rgba(229,62,62,0.05) !important; }

/* The sidebar has no account block any more — identity and Sign Out live in the
   top-bar user menu, so the rules for the footer tile and its user card are
   gone with it. */

/* ─── Topbar ────────────────────────────────────────────────── */
.main-content {
  margin-left: var(--sidebar-width);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  overflow-x: hidden;
}

.topbar {
  height: var(--topbar-height);
  background: #ffffff;
  border-bottom: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  padding: 0 1.5rem;
  gap: 1rem;
  position: sticky;
  top: 0;
  z-index: 900;
  box-shadow: 0 1px 8px rgba(42,36,32,0.07);
}

.topbar-toggle {
  display: none;
  background: none;
  border: none;
  font-size: 1.25rem;
  cursor: pointer;
  color: var(--color-text);
  padding: 0.25rem;
  border-radius: var(--radius-sm);
  transition: var(--transition);
}

.topbar-toggle:hover {
  background: var(--color-bg);
}

/* The topbar is a fixed-height flex row. The title used to be flex:1, so on
   pages with a long action row (invoice show has up to seven buttons) it was
   squeezed to min-content and wrapped mid-word — "ARW-INV-2627-0007" broke
   across two lines and spilled out of the bar. It now sits on one line at its
   natural width and the action row absorbs the pressure instead. */
.topbar-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--color-text);
  /* Never shrink: a truncated document number ("ARW-INV-2627-00…") is no more
     use than a wrapped one. The action row scrolls instead. The max-width and
     ellipsis only guard against a pathologically long title. */
  flex: 0 0 auto;
  max-width: 38%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.topbar-page-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1 1 auto;
  min-width: 0;
  /* Scroll the buttons rather than let them squash each other or shove the
     title; the scrollbar itself would not fit the bar's height. Below the
     breakpoint further down this row drops to its own line instead, because a
     scroll with no visible scrollbar just hides buttons. */
  overflow-x: auto;
  scrollbar-width: none;
}

.topbar-page-actions::-webkit-scrollbar { display: none; }

.topbar-page-actions > * { flex-shrink: 0; }

/* The row sits against the nav cluster on the right, so every page's actions
   are in the same place whatever the title's length. Done with an auto margin
   on the first button rather than justify-content:flex-end, which would put
   the head of an overflowing row out of reach of the scroll. */
.topbar-page-actions > *:first-child { margin-left: auto; }

/* ── The action row wraps instead of hiding its overflow ─────────
   A 1366px laptop cannot fit a title, seven action buttons and the nav cluster
   on one 60px line. The row used to scroll with a hidden scrollbar, so buttons
   past the edge were simply invisible with nothing to say they existed — and
   because a box that scrolls on one axis clips the other, a dropdown opened in
   the row was clipped away too, which is why the "..." menu looked dead.

   The buttons now wrap onto a second line and the bar grows to fit. This is
   driven by the content, not a breakpoint: a page with one button keeps the
   single-line bar it always had, and only a genuinely full row takes a second
   line. The nav cluster stays on the right where it was. */
.topbar {
  height: auto;
  min-height: var(--topbar-height);
}

.topbar-page-actions {
  flex-wrap: wrap;
  row-gap: 0.4rem;
  padding-block: 0.4rem;
  /* Overrides the scroll above — nothing left to clip a dropdown. */
  overflow: visible;
  justify-content: flex-end;
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-shrink: 0;
  /* The title no longer grows to fill the bar, so on pages with no page-action
     buttons this is what still holds the nav/user cluster to the right edge. */
  margin-left: auto;
}

/* Identity chip: avatar first, then name over role — the same reading order as
   the icon buttons beside it, so the whole cluster scans left to right. */
.topbar-user {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  cursor: pointer;
  padding: 0.25rem 0.7rem 0.25rem 0.25rem;
  border-radius: 50px;
  border: 1px solid var(--color-border);
  background: var(--color-card);
  transition: border-color .15s, background .15s;
}

.topbar-user:hover,
.topbar-user[aria-expanded="true"] {
  border-color: var(--color-primary);
  background: rgba(var(--color-primary-rgb), 0.05);
}

.topbar-user-info {
  text-align: left;
  line-height: 1.2;
}

.topbar-user-caret {
  font-size: 0.65rem;
  color: var(--color-text-muted);
  transition: transform .15s;
}

.topbar-user[aria-expanded="true"] .topbar-user-caret {
  transform: rotate(180deg);
  color: var(--color-primary);
}

.topbar-user-name {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-text);
}

.topbar-user-role {
  font-size: 0.725rem;
  color: var(--color-text-muted);
}

/* ─── Page Content ──────────────────────────────────────────── */
.page-content {
  padding: 1.5rem;
  flex: 1;
}

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
  gap: 1rem;
}

.page-header-title {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--color-text);
  margin: 0;
}

.breadcrumb-item.active { color: var(--color-text-muted); }
.breadcrumb-item a { color: var(--color-primary); }

/* ─── Cards ─────────────────────────────────────────────────── */
.card {
  background: var(--color-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--color-border);
  overflow: hidden;
  transition: var(--transition);
}

.card:hover { box-shadow: var(--shadow); }

.card-header {
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--color-border);
  background: transparent;
  display: flex;
  align-items: center;
  /* Titles start on the left. Headers that genuinely need a right-hand action
     say so themselves with Bootstrap's .justify-content-between, which wins
     over this. Defaulting to space-between pushed a plain "icon + title"
     header's text to the far right of the card. */
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 0.15rem 0.6rem;
}

/* A trailing button/link in a header still sits on the right, without the view
   needing .justify-content-between. :not(:only-child) keeps a header whose sole
   content is a title from being pushed across. */
.card-header > :last-child:not(:only-child):is(a, button, .btn, .btn-group, .dropdown) {
  margin-left: auto;
}

/* A description following the title belongs *under* it, not beside it.
   flex-basis:100% drops it onto its own line. Anything that looks like a
   control is excluded so title + action still share a row. */
.card-header > :is(h1, h2, h3, h4, h5, h6) + div:not([class*="btn"]):not(.dropdown):not(.d-flex) {
  flex-basis: 100%;
  margin-top: 0;
}

.card-title {
  font-size: 1rem;
  font-weight: 600;
  margin: 0;
  color: var(--color-text);
}

.card-body { padding: 1.25rem; }

/* ─── Stat Cards ─────────────────────────────────────────────── */
.stat-card {
  background: var(--color-card);
  border-radius: var(--radius);
  padding: 1.25rem;
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  gap: 1rem;
  opacity: 0;
  transition: var(--transition);
}

.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}

.stat-icon {
  width: 52px;
  height: 52px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.4rem;
  flex-shrink: 0;
}

.stat-icon.green  { background: rgba(var(--color-primary-rgb),0.1);  color: var(--color-primary); }
.stat-icon.blue   { background: rgba(42,36,32,0.1); color: var(--color-secondary); }
.stat-icon.teal   { background: rgba(0,184,138,0.1); color: var(--color-primary-light); }
.stat-icon.orange { background: rgba(214,158,46,0.1);color: var(--color-warning); }

.stat-number {
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1;
  color: var(--color-text);
}

.stat-label {
  font-size: 0.8rem;
  color: var(--color-text-muted);
  margin-top: 0.2rem;
}

.stat-trend {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.7rem;
  font-weight: 600;
  padding: 0.15rem 0.5rem;
  border-radius: 20px;
  margin-top: 0.4rem;
}

.stat-trend.up   { background: rgba(56,161,105,0.1); color: var(--color-success); }
.stat-trend.down { background: rgba(229,62,62,0.1);  color: var(--color-danger);  }
.stat-trend.flat { background: rgba(113,128,150,0.1);color: var(--color-text-muted); }

/* ─── Animate Cards ─────────────────────────────────────────── */
.animate-card {
  opacity: 0;
  animation: fadeInUp 0.5s ease forwards;
}

/* ─── Tables ─────────────────────────────────────────────────── */
.table {
  font-size: 0.875rem;
}

.table thead th {
  background: var(--color-th-bg);
  color: var(--color-text-muted);
  font-weight: 600;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
}

.table tbody td {
  padding: 0.875rem 1rem;
  vertical-align: middle;
  border-color: var(--color-border);
}

.table tbody tr {
  transition: background 0.15s;
}

.table tbody tr:hover {
  background: var(--color-row-hover);
}

/* ─── Badges ─────────────────────────────────────────────────── */
.badge-status {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.3rem 0.75rem;
  border-radius: 20px;
  font-size: 0.75rem;
  font-weight: 600;
}

.badge-status::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  display: inline-block;
}

.badge-status.active   { background: rgba(56,161,105,0.1); color: var(--color-success); }
.badge-status.active::before { background: var(--color-success); animation: pulse 2s infinite; }
.badge-status.inactive { background: rgba(229,62,62,0.1);  color: var(--color-danger);  }
.badge-status.inactive::before { background: var(--color-danger); }
/* In-flight documents (draft, sent, partially paid, open…) — neither done nor dead. */
.badge-status.pending  { background: rgba(214,158,46,0.12); color: var(--color-warning); }
.badge-status.pending::before { background: var(--color-warning); }

/* Bootstrap's .text-warning is #ffc107 — a bright yellow that disappears on the
   pale .bg-warning-subtle it is normally paired with (status pills, type counts,
   "Reserved"/"Partially Paid" badges). Darken the text tone so those badges are
   actually legible; the headline amber (--color-warning) is left alone because it
   is only used at large sizes where it reads fine. */
/* Currency shown as a tag beside an account, only for non-base currencies. */
.acc-currency-tag {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 1px 6px;
  border-radius: 5px;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: .04em;
  background: var(--color-border-soft);
  color: var(--color-text-muted);
  vertical-align: middle;
}
/* A non-base currency is worth noticing — it carries FX exposure. */
.acc-currency-tag.is-foreign {
  background: rgba(214,158,46,0.15);
  color: #8A6114;
}

.text-warning { color: #8A6114 !important; }
.bg-warning-subtle { background-color: #FDF3DD !important; }
.text-info { color: #0B6A80 !important; }
.bg-info-subtle { background-color: #DFF3F8 !important; }

.badge-role {
  display: inline-block;
  padding: 0.25rem 0.625rem;
  border-radius: 6px;
  font-size: 0.7rem;
  font-weight: 600;
  background: rgba(42,36,32,0.08);
  color: var(--color-secondary);
  border: 1px solid rgba(42,36,32,0.15);
}

.badge-system {
  display: inline-block;
  padding: 0.2rem 0.5rem;
  border-radius: 6px;
  font-size: 0.65rem;
  font-weight: 700;
  background: rgba(214,158,46,0.1);
  color: var(--color-warning);
  border: 1px solid rgba(214,158,46,0.2);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* ─── Avatar / Initials ──────────────────────────────────────── */
.avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  font-weight: 700;
  color: #fff;
  flex-shrink: 0;
  user-select: none;
}

.avatar-lg {
  width: 44px;
  height: 44px;
  font-size: 0.875rem;
}

.avatar-sm {
  width: 28px;
  height: 28px;
  font-size: 0.65rem;
}

/* Avatar color based on first letter */
.avatar[data-letter="A"], .avatar[data-letter="N"] { background: #E53E3E; }
.avatar[data-letter="B"], .avatar[data-letter="O"] { background: #DD6B20; }
.avatar[data-letter="C"], .avatar[data-letter="P"] { background: #D69E2E; }
.avatar[data-letter="D"], .avatar[data-letter="Q"] { background: #38A169; }
.avatar[data-letter="E"], .avatar[data-letter="R"] { background: var(--color-primary-light); }
.avatar[data-letter="F"], .avatar[data-letter="S"] { background: var(--color-primary); }
.avatar[data-letter="G"], .avatar[data-letter="T"] { background: #3182CE; }
.avatar[data-letter="H"], .avatar[data-letter="U"] { background: var(--color-secondary); }
.avatar[data-letter="I"], .avatar[data-letter="V"] { background: #6B46C1; }
.avatar[data-letter="J"], .avatar[data-letter="W"] { background: #D53F8C; }
.avatar[data-letter="K"], .avatar[data-letter="X"] { background: #2D3748; }
.avatar[data-letter="L"], .avatar[data-letter="Y"] { background: #E53E3E; }
.avatar[data-letter="M"], .avatar[data-letter="Z"] { background: #3182CE; }

/* ─── Toggle Switch ──────────────────────────────────────────── */
.toggle-switch {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 24px;
}

.toggle-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.toggle-slider {
  position: absolute;
  cursor: pointer;
  inset: 0;
  background: var(--color-border-strong);
  border-radius: 24px;
  transition: 0.3s;
}

.toggle-slider::before {
  content: '';
  position: absolute;
  height: 18px;
  width: 18px;
  left: 3px;
  bottom: 3px;
  background: white;
  border-radius: 50%;
  transition: 0.3s;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}

.toggle-switch input:checked + .toggle-slider {
  background: var(--color-primary);
}

.toggle-switch input:checked + .toggle-slider::before {
  transform: translateX(20px);
}

/* ─── Buttons ────────────────────────────────────────────────── */
.btn-primary-custom {
  background: var(--color-primary);
  color: white;
  border: none;
  border-radius: var(--radius-sm);
  padding: 0.625rem 1.25rem;
  font-weight: 600;
  font-size: 0.875rem;
  transition: var(--transition);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  text-decoration: none;
}

.btn-primary-custom:hover {
  background: var(--color-primary-light);
  color: white;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(var(--color-primary-rgb),0.3);
}

.btn-action {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid var(--color-border);
  background: var(--color-card);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: var(--transition);
  color: var(--color-text-muted);
  font-size: 0.875rem;
  text-decoration: none;
}

.btn-action:hover { color: var(--color-text); border-color: var(--color-border-strong); background: var(--color-bg); }
.btn-action.edit:hover  { color: var(--color-secondary); border-color: var(--color-secondary); }
.btn-action.delete:hover{ color: var(--color-danger);    border-color: var(--color-danger); }

/* ─── Form Controls ──────────────────────────────────────────── */
.form-control, .form-select {
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 0.625rem 0.875rem;
  font-size: 0.875rem;
  font-family: inherit;
  color: var(--color-text);
  /* background-color, NOT the background shorthand: the shorthand also reset
     background-image, which erased Bootstrap's caret from every <select> in the
     app and left dropdowns looking like plain text boxes. */
  background-color: #fff;
  transition: border-color 0.2s, box-shadow 0.2s;
  width: 100%;
}

/* Leave room for the caret the rule above no longer erases. */
.form-select { padding-right: 2.25rem; }

/* The padding shorthand above also flattened Bootstrap's small variants, so
   .form-control-sm / .form-select-sm rendered full height. Restore the step. */
.form-control-sm, .form-select-sm {
  padding: 0.35rem 0.65rem;
  font-size: 0.82rem;
}
.form-select-sm {
  padding-right: 2rem;
  background-position: right 0.5rem center;
}

/* ─── Extra-small button ─────────────────────────────────────────
   Bootstrap 5 ships btn-sm and btn-lg only, but ~20 views across the app ask
   for .btn-xs on compact row actions (aging reports, challan lists, comment
   delete). With no rule behind it those buttons fell back to full-size padding
   and each view patched itself with a different inline style. Defining it once
   makes them all render the same. */
/* Aging reports carry six figure columns and cannot also afford non-wrapping
   headers — the global .table th nowrap rule pushed the last column out of the
   card. Only the bucket headings wrap; the figures stay on one line. */
.aging-table th { white-space: normal; }
.aging-table th, .aging-table td { padding-left: 0.6rem; padding-right: 0.6rem; }

.btn-xs {
  --bs-btn-padding-y: 0.15rem;
  --bs-btn-padding-x: 0.55rem;
  --bs-btn-font-size: 0.75rem;
  --bs-btn-border-radius: var(--radius-sm);
  padding: 0.15rem 0.55rem;
  font-size: 0.75rem;
  line-height: 1.5;
  border-radius: var(--radius-sm);
}

/* No stepper arrows on number fields. Quantities and prices are typed, never
   nudged — the tiny up/down arrows eat horizontal room in dense line-item
   grids and a stray click silently changes a figure. Typing, arrow keys and
   the `step` attribute all keep working; only the buttons go. */
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.form-control:focus, .form-select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb),0.12);
}

.form-control.is-invalid, .form-select.is-invalid {
  border-color: var(--color-danger);
}

.form-control.is-invalid:focus {
  box-shadow: 0 0 0 3px rgba(229,62,62,0.12);
}

.form-control::placeholder,
.form-select::placeholder,
input::placeholder,
textarea::placeholder {
  color: var(--color-text-muted);
  opacity: 1;
}

.invalid-feedback {
  font-size: 0.8rem;
  color: var(--color-danger);
  margin-top: 0.25rem;
  display: block;
}

.form-label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: 0.375rem;
  display: block;
}

/* Companion to .form-label for the dense .form-control-sm grids in the
   document forms (quotation, invoice, PO…). It was only ever defined inside
   contacts/_form.php, so on every other form the label stayed inline at full
   body size and collided with its input — the "clumsy" packed look. */
.form-label-sm {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--color-text-muted);
  margin-bottom: 4px;
  display: block;
}

.input-group-custom {
  position: relative;
}

.input-group-custom .form-control {
  padding-left: 2.75rem;
}

.input-group-icon {
  position: absolute;
  left: 0.875rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-muted);
  font-size: 1rem;
  pointer-events: none;
  z-index: 1;
}

.input-group-btn {
  position: absolute;
  right: 0.75rem;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-muted);
  padding: 0.25rem;
  border-radius: 4px;
  transition: color 0.2s;
}

.input-group-btn:hover { color: var(--color-text); }

/* ─── Pagination ─────────────────────────────────────────────── */
.pagination .page-link {
  color: var(--color-primary);
  border-color: var(--color-border);
  border-radius: var(--radius-sm) !important;
  margin: 0 2px;
  font-size: 0.825rem;
  padding: 0.375rem 0.75rem;
}

.pagination .page-item.active .page-link {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: white;
}

.pagination .page-link:hover {
  background: var(--color-bg);
  border-color: var(--color-primary);
  color: var(--color-primary);
}

/* ─── Module Cards ───────────────────────────────────────────── */
.module-card {
  background: var(--color-card);
  border-radius: var(--radius);
  padding: 1.5rem;
  border: 2px solid var(--color-border);
  transition: var(--transition);
  cursor: grab;
  position: relative;
  overflow: hidden;
}

.module-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--color-primary);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s ease;
}

.module-card:hover {
  border-color: rgba(var(--color-primary-rgb),0.3);
  box-shadow: 0 8px 24px rgba(var(--color-primary-rgb),0.12);
  transform: translateY(-2px);
}

.module-card:hover::before {
  transform: scaleX(1);
}

.module-card.disabled {
  opacity: 0.6;
}

.module-icon-circle {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  background: rgba(var(--color-primary-rgb),0.1);
  color: var(--color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  margin-bottom: 0.875rem;
}

.module-name {
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--color-text);
  margin: 0 0 0.25rem;
}

.module-desc {
  font-size: 0.78rem;
  color: var(--color-text-muted);
  line-height: 1.5;
  margin: 0;
}

.drag-handle {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  color: var(--color-text-muted);
  opacity: 0;
  font-size: 0.875rem;
  transition: opacity 0.2s;
}

.module-card:hover .drag-handle { opacity: 1; }

/* ─── Role Cards ─────────────────────────────────────────────── */
.role-card {
  background: var(--color-card);
  border-radius: var(--radius);
  padding: 1.5rem;
  border: 1.5px solid var(--color-border);
  transition: var(--transition);
  position: relative;
  overflow: hidden;
}

.role-card::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--color-primary), var(--color-primary-light));
  transform: scaleX(0);
  transition: transform 0.3s ease;
}

.role-card:hover {
  box-shadow: var(--shadow);
  border-color: rgba(var(--color-primary-rgb),0.2);
  transform: translateY(-2px);
}

.role-card:hover::after {
  transform: scaleX(1);
}

.role-name {
  font-size: 1rem;
  font-weight: 700;
  color: var(--color-text);
  margin: 0 0 0.375rem;
}

.role-desc {
  font-size: 0.8rem;
  color: var(--color-text-muted);
  margin: 0 0 1rem;
}

.role-perm-summary {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  margin-top: 0.75rem;
}

/* ─── Permissions Accordion ──────────────────────────────────── */
.perm-module-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  background: var(--color-bg);
  border-radius: var(--radius-sm);
  cursor: pointer;
  user-select: none;
  transition: var(--transition);
  border: 1.5px solid var(--color-border);
}

.perm-module-header:hover {
  background: rgba(var(--color-primary-rgb),0.05);
  border-color: rgba(var(--color-primary-rgb),0.2);
}

.perm-module-body {
  padding: 1rem;
  border: 1.5px solid var(--color-border);
  border-top: none;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
}

.perm-check-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 0.75rem;
}

.perm-check-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: var(--color-bg);
  border-radius: var(--radius-sm);
  border: 1.5px solid var(--color-border);
  cursor: pointer;
  transition: var(--transition);
  font-size: 0.8rem;
  font-weight: 500;
}

.perm-check-item:hover {
  border-color: var(--color-primary);
  background: rgba(var(--color-primary-rgb),0.04);
}

.perm-check-item input:checked + span {
  color: var(--color-primary);
}

/* ─── Flash Messages ──────────────────────────────────────────── */
.flash-container {
  position: fixed;
  top: 80px;
  right: 1.5rem;
  z-index: 9999;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.flash-alert {
  border-radius: var(--radius-sm);
  padding: 0.875rem 1rem;
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  box-shadow: var(--shadow);
  animation: fadeInRight 0.3s ease;
  border: none;
}

/* ─── Searchbar ───────────────────────────────────────────────── */
.search-bar {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.search-input-wrap {
  position: relative;
  flex: 1;
  min-width: 200px;
  max-width: 360px;
}

.search-input-wrap .form-control {
  padding-left: 2.5rem;
}

.search-input-wrap .bi {
  position: absolute;
  left: 0.875rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-muted);
}

/* ─── List Bar (replaces page-header + filter card) ─────────── */
.list-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}

.list-view-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 13px;
  background: #ffffff;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-text);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s;
  line-height: 1.4;
}
.list-view-btn:hover,
.list-view-btn:focus { background: var(--color-bg-2); outline: none; border-color: var(--color-border); }
.list-view-btn .lv-count {
  font-size: 0.7rem;
  padding: 2px 6px;
  border-radius: 20px;
  background: rgba(var(--color-primary-rgb),0.12);
  color: var(--color-primary);
  font-weight: 700;
}

.list-search-wrap {
  flex: 1;
  position: relative;
  display: flex;
  align-items: center;
  min-width: 160px;
}
.list-search-wrap > .bi {
  position: absolute;
  left: 10px;
  color: var(--color-text-muted);
  font-size: 0.88rem;
  pointer-events: none;
  z-index: 1;
}
.list-search-wrap input[type="text"] {
  width: 100%;
  padding: 7px 32px 7px 32px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  background: #ffffff;
  color: var(--color-text);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.list-search-wrap input[type="text"]:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb),0.1);
}
.list-search-clear {
  position: absolute;
  right: 8px;
  background: none;
  border: none;
  color: var(--color-text-muted);
  cursor: pointer;
  padding: 0;
  font-size: 0.95rem;
  line-height: 1;
  text-decoration: none;
  display: flex;
  align-items: center;
}
.list-search-clear:hover { color: var(--color-danger); }

.list-bar-right {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.list-bar-extra {
  flex-shrink: 0;
}
.list-bar-extra select,
.list-bar-extra input[type="date"] {
  height: 34px;
  font-size: 0.82rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: #ffffff;
  color: var(--color-text);
  padding: 0 8px;
}
.list-bar-extra select:focus,
.list-bar-extra input[type="date"]:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb),0.1);
}

.list-view-menu { min-width: 200px; }
.list-view-menu .dropdown-item {
  font-size: 0.84rem;
  padding: 0.4rem 1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--color-text);
}
.list-view-menu .dropdown-item.active,
.list-view-menu .dropdown-item:active {
  background: rgba(var(--color-primary-rgb),0.08);
  color: var(--color-primary);
}
.list-view-menu .lv-count {
  font-size: 0.7rem;
  padding: 1px 6px;
  border-radius: 10px;
  background: rgba(0,0,0,0.07);
  color: var(--color-text-muted);
  font-weight: 600;
}
.list-view-menu .dropdown-item.active .lv-count {
  background: rgba(var(--color-primary-rgb),0.15);
  color: var(--color-primary);
}

/* ─── Lifecycle Empty State ──────────────────────────────────── */
.lc-empty {
  padding: 1rem 1.25rem;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto 1fr;
  column-gap: 1.5rem;
  align-items: start;
}
.lc-empty-title {
  grid-column: 1;
  grid-row: 1;
  text-align: left;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--color-text-muted);
  margin-bottom: 0.5rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.lc-flow {
  grid-column: 1;
  grid-row: 2;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 0;
  align-self: start;
}
.lc-step {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 5px 10px;
  border: 1.5px solid;
  border-radius: 6px;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  white-space: nowrap;
  background: var(--color-bg);
  min-width: 60px;
}
.lc-step i { font-size: 0.82rem; }
.lc-step.lc-draft    { border-color: #adb5bd; color: #6c757d; }
.lc-step.lc-sent     { border-color: #0d6efd; color: #0a58ca; }
.lc-step.lc-unpaid   { border-color: var(--color-warning); color: var(--color-primary-darker); background: var(--color-row-hover); }
.lc-step.lc-overdue  { border-color: #dc3545; color: #842029; border-style: dashed; background: #fff5f5; }
.lc-step.lc-partial  { border-color: var(--color-warning); color: #664d03; border-style: dashed; background: #fffbf0; }
.lc-step.lc-paid     { border-color: #198754; color: #0a3622; background: #f0fff4; }
.lc-step.lc-accepted { border-color: #198754; color: #0a3622; background: #f0fff4; }
.lc-step.lc-rejected { border-color: #dc3545; color: #842029; border-style: dashed; background: #fff5f5; }
.lc-step.lc-expired  { border-color: var(--color-warning); color: var(--color-primary-darker); border-style: dashed; background: var(--color-row-hover); }
.lc-step.lc-invoiced { border-color: #6f42c1; color: #432874; background: #f5f0ff; }
.lc-step.lc-approved { border-color: #198754; color: #0a3622; background: #f0fff4; }
.lc-step.lc-reimbursed { border-color: #0d6efd; color: #0a58ca; background: #f0f4ff; }
.lc-step.lc-submitted { border-color: #17a2b8; color: #0a6a78; }
.lc-step.lc-customer { border-color: var(--color-primary); color: var(--color-primary); background: rgba(var(--color-primary-rgb),0.04); }
.lc-step.lc-vendor   { border-color: var(--color-secondary); color: var(--color-secondary); background: rgba(42,36,32,0.04); }
.lc-step.lc-both     { border-color: #D69E2E; color: #92610a; background: rgba(214,158,46,0.06); }
.lc-step.lc-bill     { border-color: #6c757d; color: #495057; }
.lc-step.lc-void     { border-color: #adb5bd; color: #6c757d; border-style: dashed; }
.lc-step.lc-received { border-color: #198754; color: #0a3622; background: #f0fff4; }

.lc-arrow {
  color: #adb5bd;
  font-size: 0.8rem;
  flex-shrink: 0;
}
.lc-branch {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
.lc-sep {
  display: none;
}

/* Feature cards */
.lc-features {
  grid-column: 2;
  grid-row: 1 / 3;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.25rem;
  padding: 0;
  border-left: 1px solid var(--color-border);
  padding-left: 1.25rem;
  align-content: start;
}
/* Icon, title and description are three siblings. As a flex row the title
   column took its width from the text, so a short title ("Track Balances") and
   a wrapping one ("All Transactions Linked") started their descriptions at
   different places and the block read as ragged. A grid fixes the title column
   so every description starts on the same line. */
.lc-feature {
  display: grid;
  grid-template-columns: auto 8.5rem 1fr;
  align-items: start;
  column-gap: 0.6rem;
  padding: 0.35rem 0;
  text-align: left;
}
/* Roughly 40 views (most of Accounting and Warehouse) write the title and
   description inside a wrapper <div> instead of as bare siblings. That wrapper
   landed in the 8.5rem title column on its own, squeezing every description
   into a ~135px ribbon that wrapped after two or three words while the third
   column sat empty. display:contents dissolves the wrapper so its <h6> and <p>
   become grid items in their own right — both markup shapes now lay out
   identically, without touching every view. */
.lc-feature > div {
  display: contents;
}

.lc-feature-icon {
  font-size: 1rem;
  flex-shrink: 0;
  margin-top: 0.1rem;
}
.lc-feature h6 {
  font-size: 0.77rem;
  font-weight: 700;
  color: var(--color-text);
  margin-bottom: 0.1rem;
}
.lc-feature p {
  font-size: 0.71rem;
  color: var(--color-text-muted);
  line-height: 1.4;
  margin: 0;
}

@media (max-width: 767.98px) {
  .lc-empty { grid-template-columns: 1fr; }
  .lc-flow { grid-row: 2; }
  .lc-features { grid-column: 1; grid-row: 3; border-left: none; padding-left: 0; border-top: 1px solid var(--color-border); padding-top: 0.75rem; margin-top: 0.5rem; }
  .lc-flow { gap: 3px; }
  .lc-step { min-width: 52px; padding: 4px 8px; }
  /* Too narrow for a title column — stack the description under the title,
     still indented past the icon. */
  .lc-feature { grid-template-columns: auto 1fr; }
  .lc-feature p { grid-column: 2; }
}

/* ─── Auth Layout ────────────────────────────────────────────── */
.auth-wrapper {
  min-height: 100vh;
  display: flex;
}

.auth-panel-left {
  width: 50%;
  background: linear-gradient(150deg, var(--color-sidebar) 0%, var(--color-primary-dark) 55%, var(--color-primary) 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 3rem;
  position: relative;
  overflow: hidden;
  animation: fadeInLeft 0.6s ease;
}

.auth-panel-right {
  width: 50%;
  background: var(--color-card);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem;
  animation: fadeInRight 0.6s ease;
}

.auth-shape {
  position: absolute;
  border-radius: 50%;
  background: rgba(255,255,255,0.08);
  animation: float 6s ease-in-out infinite;
}

.auth-shape:nth-child(1) { width: 200px; height: 200px; top: -60px; right: -60px; animation-delay: 0s; }
.auth-shape:nth-child(2) { width: 140px; height: 140px; bottom: 80px; left: -40px; animation-delay: -2s; }
.auth-shape:nth-child(3) { width: 80px;  height: 80px;  top: 40%;  right: 15%;    animation-delay: -4s; }

.auth-brand {
  text-align: center;
  margin-bottom: 2.5rem;
  position: relative;
  z-index: 1;
}

.auth-logo-plain {
  margin-bottom: 1.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.auth-logo-plain img {
  height: 64px;
  width: auto;
  max-width: 100%;
  display: block;
  filter: drop-shadow(0 3px 10px rgba(0,0,0,0.28));
}

.auth-brand img {
  height: 70px;
  width: auto;
  filter: brightness(1.1) drop-shadow(0 2px 8px rgba(0,0,0,0.25));
}

.auth-brand-name {
  font-size: 2rem;
  font-weight: 800;
  color: #fff;
  letter-spacing: -0.03em;
}

.auth-brand-tagline {
  font-size: 0.8rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: rgba(255,255,255,0.78);
  margin-top: 0.35rem;
}

.auth-features {
  list-style: none;
  padding: 0;
  margin: 0;
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 320px;
}

.auth-features li {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.625rem 0;
  color: rgba(255,255,255,0.85);
  font-size: 0.875rem;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}

.auth-features li:last-child { border-bottom: none; }

.auth-features li .bi {
  width: 28px;
  height: 28px;
  background: rgba(255,255,255,0.15);
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.auth-form-wrap {
  width: 100%;
  max-width: 400px;
}

.auth-form-title {
  font-size: 1.625rem;
  font-weight: 700;
  color: var(--color-text);
  margin-bottom: 0.375rem;
}

.auth-form-subtitle {
  font-size: 0.875rem;
  color: var(--color-text-muted);
  margin-bottom: 2rem;
}

.btn-auth {
  background: var(--color-primary);
  color: white;
  border: none;
  width: 100%;
  padding: 0.8rem;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: var(--transition);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}

.btn-auth:hover {
  background: var(--color-primary-light);
  transform: translateY(-1px);
  box-shadow: 0 6px 20px rgba(var(--color-primary-rgb),0.3);
}

.btn-auth:disabled {
  opacity: 0.7;
  cursor: not-allowed;
  transform: none;
}

.btn-auth .spinner {
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255,255,255,0.4);
  border-top-color: white;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  display: none;
}

.btn-auth.loading .spinner { display: block; }
.btn-auth.loading .btn-text { display: none; }

/* ─── Activity Log Table ─────────────────────────────────────── */
.activity-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
}

.activity-icon.login    { background: rgba(56,161,105,0.1);  color: var(--color-success); }
.activity-icon.logout   { background: rgba(113,128,150,0.1); color: var(--color-text-muted); }
.activity-icon.create   { background: rgba(0,184,138,0.1);   color: var(--color-primary-light); }
.activity-icon.update   { background: rgba(42,36,32,0.1);   color: var(--color-secondary); }
.activity-icon.delete   { background: rgba(229,62,62,0.1);   color: var(--color-danger); }
.activity-icon.toggle   { background: rgba(214,158,46,0.1);  color: var(--color-warning); }
.activity-icon.reorder  { background: rgba(107,70,193,0.1);  color: #6B46C1; }
.activity-icon.default  { background: rgba(var(--color-primary-rgb),0.1);    color: var(--color-primary); }

/* ─── Empty State ────────────────────────────────────────────── */
.empty-state {
  text-align: center;
  padding: 3rem 1.5rem;
  color: var(--color-text-muted);
}

.empty-state-icon {
  font-size: 3rem;
  margin-bottom: 1rem;
  opacity: 0.35;
}

.empty-state p { font-size: 0.9rem; }

/* ─── 404 Page ───────────────────────────────────────────────── */
.error-page {
  min-height: 60vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 3rem;
}

.error-code {
  font-size: 7rem;
  font-weight: 900;
  line-height: 1;
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-light));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  animation: fadeInUp 0.6s ease;
}

.error-message {
  font-size: 1.25rem;
  color: var(--color-text-muted);
  margin: 1rem 0 2rem;
}

/* ─── Sidebar overlay for mobile ─────────────────────────────── */
.sidebar-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.45);
  z-index: 999;
  backdrop-filter: blur(2px);
}

.sidebar-overlay.active { display: block; }

/* ─── Responsive ─────────────────────────────────────────────── */
@media (max-width: 991.98px) {
  /* On mobile: sidebar is full-width expanded panel, hidden off-screen */
  .sidebar {
    width: 220px;
    transform: translateX(-100%);
    overflow-y: auto;
    overflow-x: visible;
  }

  .sidebar.open {
    transform: translateX(0);
  }

  /* Show brand text on mobile expanded sidebar */
  .sidebar-brand { flex-direction: row; gap: 8px; }
  .sidebar-brand-text { display: flex; }

  /* Nav items go horizontal with text on mobile */
  .snav-link {
    flex-direction: row;
    justify-content: flex-start;
    padding: 10px 14px;
    gap: 10px;
  }

  .snav-label {
    font-size: 0.875rem;
    text-transform: none;
    letter-spacing: 0;
    font-weight: 500;
    white-space: normal;
  }

  .snav-icon { font-size: 1.1rem; }
  .snav-arrow { display: block; }
  .snav-link.is-active::before { display: none; }

  /* Flyouts become accordion-style (hidden on mobile, navigate via main link) */
  .snav-fly { display: none; }

  .main-content { margin-left: 0; }

  .topbar-toggle {
    display: flex;
    align-items: center;
  }

  .auth-panel-left { display: none; }
  .auth-panel-right { width: 100%; }
}

@media (max-width: 575.98px) {
  .page-content {
    padding: 1rem;
  }

  .flash-container {
    left: 1rem;
    right: 1rem;
    max-width: none;
  }

  .stat-card {
    flex-direction: column;
    text-align: center;
    align-items: center;
  }
}

/* ─── Utilities ──────────────────────────────────────────────── */
.text-primary-custom { color: var(--color-primary) !important; }
.text-muted-custom   { color: var(--color-text-muted) !important; }
.bg-primary-custom   { background: var(--color-primary) !important; }
.fw-600              { font-weight: 600 !important; }
.fw-700              { font-weight: 700 !important; }
.gap-2               { gap: 0.5rem; }
.gap-3               { gap: 0.75rem; }

/* ═══════════════════════════════════════════════════════════════
   Bootstrap 5 — Arawali Theme Overrides
   (loaded after bootstrap.min.css so these win)
   ═══════════════════════════════════════════════════════════════ */

/* ── Global BS5 tokens ──────────────────────────────────────── */
:root {
  --bs-primary:          var(--color-primary);
  /* Must follow the theme too — every Bootstrap subtle background, focus ring
     and tint is derived from this triplet, not from --bs-primary. */
  --bs-primary-rgb:      var(--color-primary-rgb);
  --bs-link-color:       var(--color-primary);
  --bs-link-hover-color: var(--color-primary-dark);
  --bs-focus-ring-color: rgba(var(--color-primary-rgb),0.25);
}

/* ── .btn-primary ───────────────────────────────────────────── */
.btn-primary {
  --bs-btn-bg:                  var(--color-primary);
  --bs-btn-border-color:        var(--color-primary);
  --bs-btn-hover-bg:            var(--color-primary-dark);
  --bs-btn-hover-border-color:  var(--color-primary-dark);
  --bs-btn-active-bg:           var(--color-primary-darker);
  --bs-btn-active-border-color: var(--color-primary-darker);
  --bs-btn-focus-shadow-rgb:    225, 110, 30;
  --bs-btn-color:               #fff;
  --bs-btn-hover-color:         #fff;
  --bs-btn-active-color:        #fff;
  font-weight: 600;
}

/* Bootstrap keeps disabled colours in their own tokens, so overriding only
   --bs-btn-bg above left a disabled button painted Bootstrap's default blue —
   most visibly on the POS "Complete Sale" button before anything is scanned.
   Disabled should read as "not yet", so it goes flat neutral rather than a
   washed-out brand colour. */
.btn-primary:disabled,
.btn-primary.disabled,
.btn-outline-primary:disabled,
.btn-outline-primary.disabled,
.btn-success:disabled,
.btn-success.disabled,
.btn-danger:disabled,
.btn-danger.disabled {
  --bs-btn-disabled-bg:           var(--color-border-soft);
  --bs-btn-disabled-border-color: var(--color-border-strong);
  --bs-btn-disabled-color:        var(--color-text-muted);
  --bs-btn-disabled-opacity:      1;
  box-shadow: none;
  cursor: not-allowed;
}

/* ── .btn-outline-primary ───────────────────────────────────── */
.btn-outline-primary {
  --bs-btn-color:               var(--color-primary);
  --bs-btn-border-color:        var(--color-primary);
  --bs-btn-hover-bg:            var(--color-primary);
  --bs-btn-hover-border-color:  var(--color-primary);
  --bs-btn-hover-color:         #fff;
  --bs-btn-active-bg:           var(--color-primary-dark);
  --bs-btn-active-border-color: var(--color-primary-dark);
  --bs-btn-focus-shadow-rgb:    225, 110, 30;
}

/* ── .btn-secondary — soft neutral ─────────────────────────── */
.btn-secondary {
  --bs-btn-bg:            var(--color-border-soft);
  --bs-btn-border-color:  var(--color-border-strong);
  --bs-btn-color:         var(--color-secondary);
  --bs-btn-hover-bg:      var(--color-border-strong);
  --bs-btn-hover-color:   var(--color-secondary);
  --bs-btn-hover-border-color: var(--color-border-strong);
  --bs-btn-active-bg:     var(--color-border-strong);
  font-weight: 500;
}

/* ── .btn-outline-secondary ─────────────────────────────────── */
.btn-outline-secondary {
  --bs-btn-color:               #7A7168;
  --bs-btn-border-color:        var(--color-border-strong);
  --bs-btn-hover-bg:            var(--color-border-soft);
  --bs-btn-hover-color:         var(--color-secondary);
  --bs-btn-hover-border-color:  var(--color-border-strong);
  --bs-btn-active-bg:           var(--color-border-strong);
  --bs-btn-active-color:        var(--color-secondary);
  --bs-btn-focus-shadow-rgb:    113, 128, 150;
}

/* ── .btn-success ───────────────────────────────────────────── */
.btn-success {
  --bs-btn-bg:            #38A169;
  --bs-btn-border-color:  #38A169;
  --bs-btn-hover-bg:      #2F8A57;
  --bs-btn-hover-border-color: #2F8A57;
  --bs-btn-focus-shadow-rgb: 56, 161, 105;
}

/* ── Text / BG / Border helpers ─────────────────────────────── */
.text-primary  { color: var(--color-primary) !important; }
/* Honour Bootstrap's --bs-bg-opacity. Forcing a solid colour here made
   `bg-primary bg-opacity-10` render at full strength, so text-primary text on
   such a card became the same colour as its own background — invisible. */
.bg-primary    { background-color: rgba(var(--color-primary-rgb), var(--bs-bg-opacity, 1)) !important; }
.border-primary { border-color: var(--color-primary) !important; }
a { color: var(--color-primary); }
a:hover { color: var(--color-primary-dark); }

/* A table cell that links out to a related record (a quotation's contact, …).
   Undecorated so lists stay calm, underlined on hover so it is discoverable
   as a link rather than looking like plain text. */
.link-row-ref { color: var(--color-primary); text-decoration: none; }
.link-row-ref:hover { color: var(--color-primary-dark); text-decoration: underline; }

/* ── Checkboxes & radios ────────────────────────────────────── */
.form-check-input:checked {
  background-color: var(--color-primary);
  border-color: var(--color-primary);
}
.form-check-input:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 0.2rem rgba(var(--color-primary-rgb),0.2);
}

/* ── Badges ─────────────────────────────────────────────────── */
.badge.bg-primary  { background-color: var(--color-primary) !important; }
.badge.bg-secondary {
  background-color: var(--color-border-soft) !important;
  color: var(--color-secondary) !important;
}
.badge.bg-secondary-subtle { background-color: var(--color-border-soft) !important; }
.badge.text-secondary { color: var(--color-text-muted) !important; }

/* ── Nav tabs / pills active ────────────────────────────────── */
/* ── Filter tabs ────────────────────────────────────────────
   These act as the primary filter on list screens, so the current one needs
   real presence: a tinted pill, a solid 2px underline and a weight change,
   rather than a colour shift alone. */
.nav-tabs {
  border-bottom: 1px solid var(--color-border-strong);
}
.nav-tabs .nav-link {
  color: var(--color-text-muted);
  font-weight: 500;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  transition: color .15s, background .15s, border-color .15s;
}
.nav-tabs .nav-link:hover {
  color: var(--color-heading);
  background: var(--color-bg-2);
  border-bottom-color: var(--color-border-strong);
}
.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link {
  color: var(--color-primary);
  font-weight: 600;
  background: rgba(var(--color-primary-rgb), 0.07);
  border-bottom: 2px solid var(--color-primary);
}
.nav-pills .nav-link.active {
  background-color: var(--color-primary);
}

/* ── Dropdowns ──────────────────────────────────────────────── */
/* Menu entries inherited Bootstrap's 1rem, so the Settings sub-menu read a
   size larger than the top bar it hangs off and every other menu in the app.
   Bring them onto the same type scale as the sidebar flyout items. */
.dropdown-menu {
  font-size: 0.855rem;
  --bs-dropdown-link-hover-bg: var(--color-row-hover);
}
.dropdown-item {
  font-size: 0.855rem;
  padding: 0.5rem 0.9rem;
  border-radius: 6px;
}
.dropdown-menu > li > .dropdown-item i {
  font-size: 0.95rem;
  color: var(--color-text-muted);
  width: 1.05rem;
  text-align: center;
}
.dropdown-item:hover i { color: var(--color-primary); }

.dropdown-item.active,
.dropdown-item:active {
  background-color: var(--color-primary);
  color: #fff;
}
/* The selected row is a solid block of brand colour, so its icon has to turn
   white with the label. These have to out-rank `.dropdown-menu > li >
   .dropdown-item i` above — the plain `.dropdown-item.active i` form loses to
   it on specificity and the icon stayed muted grey, all but invisible against
   the fill. */
.dropdown-menu .dropdown-item.active i,
.dropdown-menu .dropdown-item:active i,
.dropdown-menu > li > .dropdown-item.active i,
.dropdown-menu > li > .dropdown-item:active i { color: #fff; }

/* ── Progress bars ──────────────────────────────────────────── */
.progress-bar { background-color: var(--color-primary); }

/* ── Spinner ────────────────────────────────────────────────── */
.spinner-border.text-primary,
.spinner-grow.text-primary { color: var(--color-primary) !important; }

/* ═══════════════════════════════════════════════════════════════
   Listing / Table UI Improvements
   ═══════════════════════════════════════════════════════════════ */

/* ── Cards ──────────────────────────────────────────────────
   One treatment for every card: soft shadow, hairline edge, no accent strip.
   Two thirds of the markup already asks for `border-0`, so the base rule below
   drops the border rather than fighting that utility with !important — the
   shadow carries the elevation. `.animate-card` no longer paints a coloured
   top strip, which only ever appeared on the ~150 cards that happened to carry
   that class. */
.card {
  border-radius: 14px;
  border: 0;
  box-shadow: var(--shadow-sm);
}

.card.animate-card {
  border-top: 0;
}

/* ── Card header ────────────────────────────────────────────── */
.card-header {
  background: linear-gradient(to right, var(--color-head-1), var(--color-head-2));
  border-bottom: 1px solid var(--color-border-strong);
  border-radius: 14px 14px 0 0 !important;

  /* Title typography lives HERE, not in each view. Headers are written two ways
     across the app — some wrap the title in an <h6>, some are bare text — and
     both must land on the same size, weight and colour. Change these three
     values to restyle every card header in the application. */
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-heading);
}

/* Make a wrapped title indistinguishable from a bare one. */
.card-header :is(h1, h2, h3, h4, h5, h6) {
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
  margin: 0;
  line-height: inherit;
}

/* Secondary text in a header (hints, counts) stays quiet and small. */
.card-header :is(small, .text-muted, .form-text) {
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--color-text-muted);
}

/* No .card-header.bg-white override any more: the views no longer set their own
   header background, so this one rule is the single source of truth. */

/* ── Table header ───────────────────────────────────────────── */
.table thead th {
  background: linear-gradient(to bottom, var(--color-th-bg), var(--color-th-bg-2));
  color: var(--color-secondary);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 0.7rem 1rem;
  border-bottom: 2px solid var(--color-border-strong);
  white-space: nowrap;
}

/* ── Table rows ─────────────────────────────────────────────── */
.table tbody td {
  padding: 0.8rem 1rem;
  vertical-align: middle;
  border-color: #EDF2F7;
  font-size: 0.865rem;
}

.table tbody tr { transition: background 0.12s; }

.table tbody tr:hover { background: var(--color-row-hover); }

.table tbody tr:last-child td { border-bottom: none; }

/* ── List bar improvements ──────────────────────────────────── */
.list-bar {
  background: #fff;
  border: 1px solid var(--color-border);
  border-radius: 12px;
  padding: 10px 12px;
  box-shadow: 0 1px 4px rgba(42,36,32,0.05);
  margin-bottom: 14px;
}

.list-view-btn {
  background: var(--color-th-bg);
  border: 1px solid var(--color-border-strong);
  border-radius: 8px;
  color: var(--color-secondary);
  font-weight: 600;
  font-size: 0.82rem;
}
.list-view-btn:hover { background: var(--color-bg-2); }

.list-search-wrap input[type="text"] {
  background: var(--color-head-1);
  border: 1px solid var(--color-border-strong);
  border-radius: 8px;
}
.list-search-wrap input[type="text"]:focus {
  background: #fff;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb),0.1);
}

.list-bar-extra select,
.list-bar-extra input[type="date"] {
  background: var(--color-head-1);
  border: 1px solid var(--color-border-strong);
  border-radius: 8px;
  color: var(--color-secondary);
}

/* ── Topbar action buttons (sm) ─────────────────────────────── */
.btn-sm {
  border-radius: 7px;
  font-size: 0.82rem;
  padding: 0.35rem 0.85rem;
}

/* ── Status badges ───────────────────────────────────────────── */
.badge {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  border-radius: 6px;
  padding: 0.3em 0.65em;
}

/* Bootstrap subtle variants → Arawali palette */
.bg-success-subtle  { background-color: rgba(56,161,105,0.1)  !important; }
.bg-danger-subtle   { background-color: rgba(229,62,62,0.1)   !important; }
.bg-warning-subtle  { background-color: rgba(214,158,46,0.1)  !important; }
.bg-primary-subtle  { background-color: rgba(var(--color-primary-rgb),0.1)  !important; }
.text-success { color: #2F8A57 !important; }
.text-danger  { color: #C53030 !important; }
.text-warning { color: #B7791F !important; }

/* ── Pagination ─────────────────────────────────────────────── */
.pagination { gap: 3px; }
.pagination .page-link {
  border-radius: 7px !important;
  border: 1px solid var(--color-border-strong);
  color: var(--color-secondary);
  font-size: 0.82rem;
  font-weight: 500;
  padding: 0.4rem 0.8rem;
  transition: all 0.15s;
}
.pagination .page-link:hover {
  background: #EEF5FB;
  border-color: var(--color-primary);
  color: var(--color-primary);
}
.pagination .page-item.active .page-link {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
  font-weight: 700;
  box-shadow: 0 2px 8px rgba(var(--color-primary-rgb),0.3);
}
.pagination .page-item.disabled .page-link {
  background: var(--color-head-1);
  color: var(--color-text-muted);
  border-color: var(--color-border);
}

/* ── Action buttons in table rows ───────────────────────────── */
.btn-action {
  width: 30px;
  height: 30px;
  border-radius: 7px;
  border: 1px solid var(--color-border);
  background: var(--color-head-1);
}
/* All three actions get the same hover treatment, differing only in hue.
   View previously carried its colour inline, which outranked :hover and left it
   as the one button with no feedback. */
.btn-action:hover        { background: var(--color-bg-2); border-color: var(--color-border-strong); }
.btn-action.view         { color: var(--color-secondary); }
.btn-action.view:hover   { color: var(--color-primary); border-color: var(--color-primary); background: rgba(var(--color-primary-rgb),0.06); }
.btn-action.edit:hover   { color: var(--color-primary); border-color: var(--color-primary); background: rgba(var(--color-primary-rgb),0.06); }
.btn-action.delete:hover { color: var(--color-danger); border-color: var(--color-danger); background: rgba(229,62,62,0.06); }

/* ── Empty state ────────────────────────────────────────────── */
.empty-state {
  padding: 3.5rem 2rem;
}
.empty-state-icon {
  font-size: 2.8rem;
  color: var(--color-border-strong);
  margin-bottom: 0.875rem;
  opacity: 1;
}
.empty-state h6 {
  color: var(--color-secondary);
  font-size: 0.95rem;
  font-weight: 700;
}
.empty-state p {
  font-size: 0.82rem;
  color: var(--color-text-muted);
}

/* ── Modal ──────────────────────────────────────────────────── */
.modal-header {
  border-bottom: 1px solid var(--color-border);
  padding: 1rem 1.25rem 0.875rem;
}
.modal-footer {
  border-top: 1px solid var(--color-border);
  padding: 0.875rem 1.25rem;
}
.modal-content {
  border: none;
  border-radius: 14px;
  box-shadow: 0 20px 60px rgba(42,36,32,0.15);
}

/* ── Print (global) ─────────────────────────────────────────── */
@media print {
  .sidebar, .sidebar-overlay, .topbar, .no-print { display: none !important; }
  .app-wrapper { display: block !important; }
  .page-content, .content-area, main { margin-left: 0 !important; padding: 0 !important; }
  .card { border: 1px solid #ddd !important; box-shadow: none !important; page-break-inside: avoid; }
  a { color: inherit !important; text-decoration: none !important; }
  body { background: #fff !important; font-size: 10pt; }
}

/* ═══════════════════════════════════════════════════════════════
   THEMED SURFACES
   Loaded last so it wins over the earlier duplicate table rules.
   Everything here reads from the tokens in :root, so it follows
   whichever theme is selected in Settings → Appearance.
   ═══════════════════════════════════════════════════════════════ */

/* ── Headings ──────────────────────────────────────────────────
   Element selectors only, so Bootstrap utilities (.text-primary,
   .text-white, .text-muted) still win where a view sets one.     */
h1, h2, h3, h4, h5, h6,
.card-title, .section-title, .page-title {
  color: var(--color-heading);
}

/* …except on dark or brand-coloured surfaces, where the container already sets
   a light colour and the heading must inherit it. Without this, an element-level
   heading rule beats inheritance and paints dark text on a dark panel. */
.sidebar h1, .sidebar h2, .sidebar h3, .sidebar h4, .sidebar h5, .sidebar h6,
.dash-greeting h1, .dash-greeting h2, .dash-greeting h3,
.dash-greeting h4, .dash-greeting h5, .dash-greeting h6,
.text-white h1, .text-white h2, .text-white h3,
.text-white h4, .text-white h5, .text-white h6,
h1.text-white, h2.text-white, h3.text-white,
h4.text-white, h5.text-white, h6.text-white,
[class*="bg-primary"] h1, [class*="bg-primary"] h2, [class*="bg-primary"] h3,
[class*="bg-primary"] h4, [class*="bg-primary"] h5, [class*="bg-primary"] h6,
[class*="bg-dark"] h1, [class*="bg-dark"] h2, [class*="bg-dark"] h3,
[class*="bg-dark"] h4, [class*="bg-dark"] h5, [class*="bg-dark"] h6 {
  color: inherit;
}

/* ── Table header ─────────────────────────────────────────────── */
.table thead th {
  background: linear-gradient(to bottom, var(--color-th-bg), var(--color-th-bg-2));
  color: var(--color-th-text);
  border-bottom: 2px solid var(--color-border-strong);
}

/* ── Alternate (striped) rows + hover ──────────────────────────
   Bootstrap 5.3 paints cell backgrounds through --bs-table-bg-type
   and --bs-table-bg-state, which sit above a background set on the
   row. Set both mechanisms so the stripe shows regardless of which
   table variant a view uses.                                      */
@media screen {
  .table {
    --bs-table-striped-bg: var(--color-row-alt);
    --bs-table-hover-bg:   var(--color-row-hover);
  }

  .table > tbody > tr:nth-of-type(even) {
    background-color: var(--color-row-alt);
  }
  .table > tbody > tr:nth-of-type(even) > * {
    --bs-table-bg-type: var(--color-row-alt);
  }

  .table > tbody > tr:hover {
    background-color: var(--color-row-hover);
  }
  .table > tbody > tr:hover > * {
    --bs-table-bg-state: var(--color-row-hover);
  }

  /* Dashboard and report tables are styled by hand and never carry the
     .table class, so they need the stripe applied to their cells directly
     (a background on the row loses to any background set on a td). */
  .dash-table > tbody > tr:nth-of-type(even) > td,
  .tb-table   > tbody > tr:nth-of-type(even) > td,
  .pl-table   > tbody > tr:nth-of-type(even) > td {
    background-color: var(--color-row-alt);
  }
  .dash-table > tbody > tr:hover > td,
  .tb-table   > tbody > tr:hover > td,
  .pl-table   > tbody > tr:hover > td {
    background-color: var(--color-row-hover);
  }

  /* Rows the app colours deliberately (selected, warning, totals)
     keep their own background — don't stripe over meaning. */
  .table > tbody > tr.table-active,
  .table > tbody > tr.table-success,
  .table > tbody > tr.table-warning,
  .table > tbody > tr.table-danger,
  .table > tbody > tr.no-stripe {
    background-color: revert;
  }
  .table > tbody > tr.table-active > *,
  .table > tbody > tr.table-success > *,
  .table > tbody > tr.table-warning > *,
  .table > tbody > tr.table-danger > *,
  .table > tbody > tr.no-stripe > * {
    --bs-table-bg-type: initial;
  }
}

/* ═══════════════════════════════════════════════════════════════
   TABLE ACTION CELLS
   The last column of a list table holds its row actions. Views write those
   controls three different ways (.btn-action, .btn-sm.btn-outline-*, and a
   delete wrapped in an inline <form>), which left them sitting on different
   baselines with uneven gaps — most visibly on Job Cards and Mechanics.
   Laying the cell out here makes every list align the same way, whatever
   markup the view happens to use.
   ═══════════════════════════════════════════════════════════════ */
/* Only cells that actually hold controls. Applied to every last cell, this
   also caught the value column of two-column key/value tables — the ones in
   detail sidebars — so a long narration or note could not wrap and was clipped
   at the card edge instead. */
.table td:last-child:has(> .btn),
.table td:last-child:has(> .btn-action),
.table td:last-child:has(> form),
.table td:last-child:has(> .dropdown),
.table td:last-child:has(> .d-flex) {
  white-space: nowrap;
}

/* Controls sit on one row, centred, evenly spaced. */
.table td:last-child > .btn,
.table td:last-child > .btn-action,
.table td:last-child > form,
.table td:last-child > .dropdown {
  vertical-align: middle;
  margin: 0 1px;
}

/* An inline <form> around a delete button is a layout wrapper, not content —
   make it behave like the buttons beside it instead of a text baseline box. */
.table td:last-child form.d-inline,
.table td:last-child form {
  display: inline-flex;
  align-items: center;
  margin-bottom: 0;
}

/* Where a view already groups the actions in a flex row, keep that but
   normalise the spacing so it matches the ungrouped lists. */
.table td:last-child > .d-flex {
  gap: 0.25rem;
  align-items: center;
}

/* Equal footprint for both button idioms so rows line up column-to-column. */
.table td:last-child .btn-sm,
.table td:last-child .btn-action {
  min-width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 .45rem;
  line-height: 1;
}

/* ═══════════════════════════════════════════════════════════════
   TOP-BAR NAV (Dashboard / Settings / account)
   Round icon buttons rather than labelled ones: the row then takes the same
   width on every page, so it never competes with a long title or a crowded
   page-action row for the bar. The name is in the tooltip.
   ═══════════════════════════════════════════════════════════════ */
.topbar-icons {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

.topbar-icon-btn {
  width: 38px;
  height: 38px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-border);
  border-radius: 50%;
  background: var(--color-card);
  color: var(--color-text-muted);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  transition: color .15s, background .15s, border-color .15s, box-shadow .15s;
}

.topbar-icon-btn:hover,
.topbar-icon-btn[aria-expanded="true"] {
  color: var(--color-primary);
  border-color: var(--color-primary);
  background: rgba(var(--color-primary-rgb), 0.08);
}

/* The section you are in reads as a filled tile, the way the sidebar marks the
   active group. */
.topbar-icon-btn.is-active,
.topbar-icon-btn.is-active[aria-expanded="true"] {
  color: #fff;
  background: var(--color-primary);
  border-color: var(--color-primary);
  box-shadow: 0 2px 8px rgba(var(--color-primary-rgb), 0.30);
}

.topbar-icon-btn.is-active:hover {
  color: #fff;
  background: var(--color-primary-dark);
  border-color: var(--color-primary-dark);
}

.topbar-divider {
  width: 1px;
  height: 24px;
  flex-shrink: 0;
  background: var(--color-border);
  margin: 0 0.15rem;
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* ── Menus hanging off the cluster ──────────────────────────────
   Shared by the Settings menu and the user menu so both read as one
   component: a sectioned list, headings in small caps. */
.topbar-menu {
  min-width: 230px;
  padding: 0.3rem 0.35rem 0.35rem;
  margin-top: 0.5rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
}

.topbar-menu .dropdown-item {
  display: flex;
  align-items: center;
  gap: 0.55rem;
}

/* Group heading — a label, not a target. */
.topbar-menu-label {
  padding: 0.55rem 0.65rem 0.3rem;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* The heading above the first group would double the panel's top padding. */
.topbar-menu-label:first-child { padding-top: 0.25rem; }

/* Wider than the Settings menu so an ordinary work address fits the identity
   card on one line; anything longer still wraps rather than being cut. */
.topbar-user-menu { min-width: 292px; }

/* Identity card at the head of the user menu: this is where the name and
   e-mail live now that the sidebar has no account tile. */
.topbar-menu-user {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.65rem 0.7rem;
  margin-bottom: 0.25rem;
  border-bottom: 1px solid var(--color-border);
}

.topbar-menu-user-text { min-width: 0; }

.topbar-menu-user-name {
  font-weight: 600;
  font-size: 0.85rem;
  line-height: 1.25;
  color: var(--color-text);
}

.topbar-menu-user-mail {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  overflow-wrap: anywhere;
}

.topbar-menu-danger,
.topbar-menu-danger i { color: var(--color-danger) !important; }

.topbar-menu-danger:hover,
.topbar-menu-danger:focus {
  background: rgba(229, 62, 62, 0.07) !important;
  color: var(--color-danger) !important;
}

.topbar-menu-danger:hover i { color: var(--color-danger) !important; }

/* Phones: the chip collapses to the avatar alone (name and role are hidden by
   the d-none/d-md-block pair), so keep the cluster tight. */
@media (max-width: 575.98px) {
  .topbar-icon-btn { width: 34px; height: 34px; font-size: 0.92rem; }
  .topbar-user { padding: 0.2rem 0.4rem 0.2rem 0.2rem; gap: 0.3rem; }
  .topbar-actions { gap: 0.35rem; }
}

/* ═══════════════════════════════════════════════════════════════
   SIDEBAR LOGO
   The brand mark must sit inside the header band without touching or
   overflowing its edges — `max-height:100%` alone let a tall source image
   crop against the band. Constrain both axes and centre it.
   ═══════════════════════════════════════════════════════════════ */
.sidebar-header {
  overflow: hidden;
}
.sidebar-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 0;
}
.sidebar-brand img {
  max-height: calc(var(--topbar-height) - 18px);
  max-width: calc(var(--sidebar-width) - 22px);
  width: auto;
  height: auto;
  object-fit: contain;
  padding: 0;
}

/* ═══════════════════════════════════════════════════════════════
   ROW ACTION BUTTONS — one language everywhere
   Lists were written three ways (.btn-action, .btn-sm.btn-outline-*, and
   inline-form deletes), which produced different sizes and colours per page.
   Any of those idioms inside a table's action cell now renders identically:
   a neutral square that takes on meaning only on hover.
   ═══════════════════════════════════════════════════════════════ */
/* A btn-group in an action cell is just a row of actions — un-join it so it
   matches the lists that use separate buttons. */
.table td:last-child .btn-group {
  display: inline-flex;
  gap: 0.25rem;
}
.table td:last-child .btn-group > .btn {
  border-radius: var(--radius-sm) !important;
}

/* Match every idiom: .btn-action, and any outline button at any size.

   A fixed `width: 30px` here squared off icon-only row actions, but it hit
   labelled buttons in the same cell too — the "View" on the ageing reports and
   the challan list rendered as a 30px box with the word spilling out past its
   own border. Only .btn-action, which exists to be an icon square, keeps the
   fixed width; a general outline button gets the same height and a 30px floor
   and then sizes to whatever label it carries. */
.table td:last-child .btn-action {
  width: 30px;
  padding: 0;
}

.table td:last-child .btn-action,
.table td:last-child .btn[class*="btn-outline-"] {
  min-width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-card);
  color: var(--color-text-muted);
  font-size: 0.85rem;
  line-height: 1;
  transition: color .15s, background .15s, border-color .15s;
}

/* Neutral by default; hue appears on hover so rows stay calm at rest. */
.table td:last-child .btn-action:hover,
.table td:last-child .btn[class*="btn-outline-"]:hover {
  color: var(--color-primary);
  border-color: var(--color-primary);
  background: rgba(var(--color-primary-rgb), 0.08);
}
/* Destructive actions are the one exception — they announce themselves. */
.table td:last-child .btn-action.delete:hover,
.table td:last-child .btn-outline-danger:hover,
.table td:last-child .delete-btn:hover {
  color: var(--color-danger);
  border-color: var(--color-danger);
  background: rgba(229, 62, 62, 0.08);
}

/* Disabled actions (e.g. delete blocked by dependent records) read as inert. */
.table td:last-child .btn:disabled,
.table td:last-child .btn.disabled {
  opacity: .4;
  pointer-events: none;
}

/* ── Bootstrap "info" follows the theme ─────────────────────────
   .text-info / .bg-info are used ~35 times for informational counters and
   badges. Bootstrap paints them cyan, which sits outside the palette in every
   theme. Success / danger / warning keep their own hues because those carry
   meaning; "info" does not, so it takes the brand accent. */
.text-info { color: var(--color-primary) !important; }
.bg-info   { background-color: rgba(var(--color-primary-rgb), var(--bs-bg-opacity, 1)) !important; }
.bg-info-subtle  { background-color: rgba(var(--color-primary-rgb), 0.12) !important; }
.text-info-emphasis { color: var(--color-primary-dark) !important; }
.border-info { border-color: var(--color-primary) !important; }

/* ══════════════════════════════════════════════════════════════════════════
   FINANCIAL STATEMENTS
   Shared by Trial Balance, P&L, Balance Sheet, Cash Flow, Changes in Equity
   and the General Ledger. These are the documents that leave the building, so
   they read as one set rather than six pages that each grew their own type
   scale. Paired with partials/_statement_header.php and _statement_stamp.php.
   ═══════════════════════════════════════════════════════════════════════ */

.stmt-head {
  text-align: center;
  padding: 0 0 0.9rem;
  margin-bottom: 1.25rem;
  border-bottom: 2px solid var(--color-heading);
}
.stmt-company {
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--color-heading);
  text-transform: uppercase;
  letter-spacing: 0.045em;
  line-height: 1.3;
}
.stmt-meta {
  font-size: 0.76rem;
  color: var(--color-text-muted);
  line-height: 1.55;
}
.stmt-title {
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--color-heading);
  margin: 0.6rem 0 0;
  letter-spacing: -0.005em;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}
.stmt-period {
  font-size: 0.8rem;
  color: #475569;
  margin-top: 3px;
}
.stmt-units {
  font-size: 0.72rem;
  color: #94A3B8;
  font-style: italic;
  margin-top: 2px;
}

/* Preparation stamp */
.stmt-stamp {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  margin: 0.9rem auto 0;
  padding-top: 0.5rem;
  border-top: 1px solid var(--color-border, #E4ECF3);
  font-size: 0.7rem;
  color: #94A3B8;
}

/* Figures line up in columns wherever a statement prints money */
.stmt-num,
.tb-acc-amt, .tb-group-amt,
.cf-amt {
  font-variant-numeric: tabular-nums;
}

/* Print: statements should look like statements, not like screenshots of an app */
@media print {
  .stmt-head { break-inside: avoid; }
  .stmt-stamp { color: #666; }
  .stmt-head, .stmt-title {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}
