/* ==========================================================================
   Reusable Components
   ========================================================================== */

svg.icon {
  display: block;
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
}

[data-icon] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
}

/* ---- Buttons ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 40px;
  padding: 8px var(--space-4);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    color var(--transition-fast), box-shadow var(--transition-fast), transform var(--transition-fast);
  white-space: nowrap;
}

.btn:active {
  transform: translateY(1px);
}

/* Keyboard-only focus ring (mouse/touch clicks don't trigger :focus-visible),
   applied broadly so every interactive control gets a visible indicator
   consistent with .stat-card-link's existing treatment below. */
.btn:focus-visible,
.btn-icon:focus-visible,
.dropdown-item:focus-visible,
.tab-btn:focus-visible,
.pagination-btn:focus-visible,
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid rgba(198, 154, 109, 0.4);
  outline-offset: 2px;
}

.btn .icon {
  width: 16px;
  height: 16px;
}

.btn-sm {
  min-height: 32px;
  padding: 6px var(--space-3);
  font-size: var(--fs-xs);
}

.btn-lg {
  min-height: 48px;
  padding: 12px var(--space-5);
  font-size: var(--fs-md);
}

.btn-primary {
  background: var(--color-primary);
  color: #fff;
}
.btn-primary:hover {
  background: var(--color-primary-light);
}

.btn-secondary {
  background: var(--color-secondary-dark);
  color: #fff;
}
.btn-secondary:hover {
  filter: brightness(0.92);
}

.btn-outline {
  background: var(--surface-control);
  border-color: var(--color-border-strong);
  color: var(--color-text);
}
.btn-outline:hover {
  border-color: var(--color-secondary);
  color: var(--color-secondary-dark);
  background: var(--surface-elevated);
}

.btn-ghost {
  background: transparent;
  color: var(--color-text-muted);
  border: 0.2px solid var(--color-primary);
  border-radius: var(--radius-sm);
}
.btn-ghost:hover {
  background: var(--color-bg);
  color: var(--color-text);
}

.btn-danger {
  background: var(--color-danger);
  color: #fff;
}
.btn-danger:hover {
  filter: brightness(0.92);
}

.btn-success {
  background: var(--color-success);
  color: #fff;
}

.btn-warning {
  background: var(--color-warning);
  color: #fff;
}

.btn-link {
  min-height: auto;
  padding: var(--space-1);
  color: var(--module-accent);
  border-radius: var(--radius-sm);
}

.btn-success:hover,
.btn-warning:hover {
  filter: brightness(0.92);
}

.btn.is-loading {
  pointer-events: none;
  color: transparent;
  position: relative;
}

.btn.is-loading::after {
  content: "";
  position: absolute;
  width: 16px;
  height: 16px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: #fff;
  animation: spin 0.7s linear infinite;
}

.btn-danger-outline {
  background: transparent;
  border-color: var(--color-danger);
  color: var(--color-danger);
}
.btn-danger-outline:hover {
  background: var(--color-danger-bg);
}

.btn-success-outline {
  background: transparent;
  border-color: var(--color-success);
  color: var(--color-success);
}
.btn-success-outline:hover {
  background: var(--color-success-bg);
}

.btn-icon {
  width: 38px;
  height: 38px;
  padding: 0;
  border-radius: var(--radius-md);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  vertical-align: middle;
}

.btn-icon .icon,
.modal-close .icon,
.topbar-icon-btn .icon,
.theme-toggle .icon {
  margin: auto;
}

.btn-icon-sm {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
}

.btn-block {
  width: 100%;
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

.btn-group {
  display: inline-flex;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--color-border-strong);
}
.btn-group .btn {
  border-radius: 0;
  border: none;
  border-right: 1px solid var(--color-border-strong);
}
.btn-group .btn:last-child {
  border-right: none;
}

/* ---- Cards ---- */
.card {
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-level-1);
  transition: box-shadow var(--transition-fast), transform var(--transition-fast);
}

.card-body {
  padding: var(--space-4);
}

.card > .card-body.pb-0.toolbar,
.card > .card-body.pb-0:has(> .toolbar) {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-bottom: var(--space-4);
  background: var(--surface-section);
  border-bottom: 1px solid var(--border-default);
}

.card > .card-body.pb-0.toolbar.toolbar-left,
.card > .card-body.pb-0:has(> .toolbar.toolbar-left) {
  justify-content: flex-start;
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  background: var(--surface-section);
  border-bottom: 1px solid var(--border-default);
  gap: var(--space-3);
  flex-wrap: wrap;
}

.card-header h3 {
  font-size: var(--fs-sm);
}

/* Every top-level form card uses the same branded header treatment as form
   dialogs, including settings and full-page workflow forms. */
.card:has(form) > .card-header,
form > .card > .card-header {
  color: var(--color-text-on-primary);
  background: var(--color-primary);
  border-bottom-color: var(--color-primary-dark);
}

.card:has(form) > .card-header h1,
.card:has(form) > .card-header h2,
.card:has(form) > .card-header h3,
form > .card > .card-header h1,
form > .card > .card-header h2,
form > .card > .card-header h3 {
  color: var(--color-text-on-primary);
}

.card:has(form) > .card-header a,
form > .card > .card-header a {
  color: rgba(255, 255, 255, 0.86);
}

.card-footer {
  padding: var(--space-3) var(--space-4);
  background: var(--surface-section);
  border-top: 1px solid var(--border-default);
}

.card-footer-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
}

.card-hover:hover {
  box-shadow: var(--shadow-level-2);
  transform: translateY(-2px);
}

/* ---- Statistic / KPI Cards ---- */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-3);
}

.stat-card {
  background: var(--surface-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  box-shadow: var(--shadow-level-1);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  position: relative;
  overflow: hidden;
  transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}

.stat-card-link {
  color: inherit;
  text-decoration: none;
}

.stat-card-link:focus-visible {
  outline: 3px solid rgba(198, 154, 109, 0.4);
  outline-offset: 2px;
}

.stat-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--module-accent);
}

/* Top accent follows the same semantic tone as the card's icon, so alerts
   (warning/danger) read as visually distinct from routine metrics instead
   of every card sharing one accent color. */
.stat-card.tone-secondary::before { background: var(--color-secondary); }
.stat-card.tone-success::before { background: var(--color-success); }
.stat-card.tone-warning::before { background: var(--color-warning); }
.stat-card.tone-danger::before { background: var(--color-danger); }
.stat-card.tone-info::before { background: var(--color-info); }

.stat-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-level-2);
}

.stat-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.stat-card__icon {
  width: 42px;
  height: 42px;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.stat-card__icon.tone-primary { background: var(--color-primary-bg); color: var(--color-text); }
.stat-card__icon.tone-secondary { background: var(--color-secondary-bg); color: var(--color-secondary-dark); }
.stat-card__icon.tone-success { background: var(--color-success-bg); color: var(--color-success); }
.stat-card__icon.tone-warning { background: var(--color-warning-bg); color: var(--color-warning); }
.stat-card__icon.tone-danger { background: var(--color-danger-bg); color: var(--color-danger); }
.stat-card__icon.tone-info { background: var(--color-info-bg); color: var(--color-info); }

.stat-card__label {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-weight: var(--fw-medium);
}

.stat-card__value {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  letter-spacing: -0.01em;
}

.stat-card__trend {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

.stat-card__trend.up { color: var(--color-success); }
.stat-card__trend.down { color: var(--color-danger); }
.stat-card__trend.flat { color: var(--color-text-muted); }

.stat-card-link {
  color: inherit;
  text-decoration: none;
}

.stat-card-link:focus-visible {
  outline: 3px solid rgba(198, 154, 109, 0.4);
  outline-offset: 2px;
}

.supplier-section-breakdown {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-3);
}

.supplier-section-breakdown__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  color: inherit;
  text-decoration: none;
  transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}

a.supplier-section-breakdown__item:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-level-1);
  border-color: var(--color-secondary);
}

.supplier-section-breakdown__item--total {
  background: var(--surface-elevated);
  font-weight: var(--fw-semibold);
}

.supplier-section-breakdown__label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
}

.supplier-section-breakdown__value {
  font-weight: var(--fw-semibold);
}

/* ---- Supplier Summary Card (Multi-Supplier PO/GRN/Invoice workspaces) ----
   Compact sibling of .supplier-section-breakdown above (same data, same
   card-per-section-plus-total shape) rendered as a clickable <button> that
   focuses/highlights its own supplier panel -- see focusSupplierPanel() in
   purchase-payments.js. */
.supplier-summary-card {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--surface-elevated);
  color: inherit;
  font: inherit;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin: 0 var(--space-4);
  cursor: pointer;
  transition: transform var(--transition-fast), box-shadow var(--transition-fast), border-color var(--transition-fast);
}

.supplier-summary-card:hover,
.supplier-summary-card:focus-visible {
  transform: translateY(-1px);
  box-shadow: var(--shadow-level-1);
  border-color: var(--color-secondary);
}

.supplier-summary-card__header {
  margin-bottom: var(--space-2);
}

.supplier-summary-card__name {
  font-weight: var(--fw-semibold);
}

.supplier-summary-card__rows {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
}

.supplier-summary-card__row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}

.supplier-summary-card__value {
  font-weight: var(--fw-semibold);
  color: inherit;
}

.supplier-summary-card__total {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border-default);
  font-weight: var(--fw-semibold);
}

.supplier-summary-card__empty {
  margin: 0;
  font-size: var(--fs-sm);
}

/* Persistent state while a supplier's panel is the focused one; flash is the
   brief attention-pulse right after the click (removed by JS ~1.2s later). */
.supplier-panel--active {
  border-color: var(--color-secondary);
  box-shadow: var(--shadow-level-1);
}

.supplier-panel--flash {
  animation: supplier-panel-flash 1.2s ease-out;
}

@keyframes supplier-panel-flash {
  0% {
    background-color: rgba(198, 154, 109, 0.22);
  }
  100% {
    background-color: var(--surface-card);
  }
}

/* Generic deep-link row highlight -- e.g. a table row landed on via a
   ?view=<id>-style link from another page (see the Control Account
   Reconciliation workspace's one-click navigation, assets/js/reports.js).
   Unlike .supplier-panel--flash above (which settles on --surface-card,
   correct for a card), this settles on transparent so it works on any
   plain <tr>/table row background, striped or not. */
.row-flash {
  animation: row-flash 1.6s ease-out;
}

@keyframes row-flash {
  0% {
    background-color: rgba(198, 154, 109, 0.28);
  }
  100% {
    background-color: transparent;
  }
}

/* ---- Badges ---- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: var(--radius-full);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
  line-height: 1.6;
}

.badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.badge-success { background: var(--color-success-bg); color: var(--color-success); }
.badge-warning { background: var(--color-warning-bg); color: var(--color-warning); }
.badge-danger { background: var(--color-danger-bg); color: var(--color-danger); }
.badge-info { background: var(--color-info-bg); color: var(--color-info); }
.badge-secondary { background: var(--color-secondary-bg); color: var(--color-secondary-dark); }
.badge-neutral { background: var(--color-bg); color: var(--color-text-muted); border: 1px solid var(--color-border); }
.badge-neutral::before { display: none; }

/* Canonical workflow statuses. Existing tone classes remain supported while
   the enhancer applies these semantic classes consistently across modules. */
.badge-status--draft,
.badge-status--cancelled { background: var(--color-bg); color: var(--color-text-muted); border: 1px solid var(--color-border); }
.badge-status--pending,
.badge-status--waiting-approval { background: var(--color-warning-bg); color: var(--color-warning); }
.badge-status--approved,
.badge-status--posted,
.badge-status--paid,
.badge-status--completed { background: var(--color-success-bg); color: var(--color-success); }
.badge-status--rejected { background: var(--color-danger-bg); color: var(--color-danger); }

.badge-branch {
  background: var(--color-secondary-dark);
  color: #fff;
}
.badge-branch::before { display: none; }

.badge-role {
  background: var(--color-primary-bg);
  color: var(--color-text);
  border: 1px solid var(--color-border);
}
.badge-role::before { display: none; }

/* Supplier Ledger transaction-type badge (assets/js/supplier-ledger.js) --
   an icon instead of the plain dot, so Invoice Reversal reads unmistakably
   differently from Payment even though both can be a ledger "credit". */
.ledger-type-badge::before { display: none; }
.ledger-type-badge .icon { width: 14px; height: 14px; }

/* ---- Forms ---- */
.form-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: var(--space-3);
}

.form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-3);
}

.form-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  line-height: var(--lh-caption);
}

.form-label .required {
  color: var(--color-danger);
}

.form-hint {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

.form-hint.inline {
  display: inline;
}

.form-control[readonly] {
  background: var(--surface-section);
  color: var(--color-text-muted);
  border-color: var(--border-default);
  cursor: not-allowed;
}

.form-control:disabled {
  background: var(--surface-section);
  color: var(--color-text-faint);
  border-color: var(--border-default);
  cursor: not-allowed;
  opacity: 1;
}

.form-control[aria-invalid="true"],
.form-control.is-invalid {
  border-color: var(--color-danger);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-danger) 18%, transparent);
}

.form-error {
  color: var(--color-danger);
  font-size: var(--fs-xs);
  line-height: var(--lh-caption);
}

.form-section,
.section-card {
  background: var(--surface-section);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  box-shadow: var(--shadow-level-1);
}

.form-section + .form-section,
.section-card + .section-card {
  margin-top: var(--space-4);
}

.form-section__header,
.form-section-label {
  margin-bottom: var(--space-4);
  padding-left: var(--space-3);
  border-left: 3px solid var(--module-accent);
  color: var(--color-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}

/* Branded subheaders make long forms and generated workflow workspaces
   scannable without turning every subsection into another full modal header. */
form .section-title.compact,
.modal-body .section-title.compact,
.card-body:has(> form) > h3:first-child {
  min-height: 42px;
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-4);
  color: var(--color-text);
  background: color-mix(in srgb, var(--color-primary) 9%, var(--surface-section));
  border: 1px solid color-mix(in srgb, var(--color-primary) 24%, var(--border-default));
  border-left: 4px solid var(--color-primary);
  border-radius: var(--radius-sm);
}

form .section-title.compact h2,
.modal-body .section-title.compact h2 {
  padding-left: 0;
  color: inherit;
  border-left: 0;
}

.card-body:has(> form) > h3:first-child {
  display: flex;
  align-items: center;
  font-size: var(--fs-base);
}

/* Compact spreadsheet-style variant for inputs embedded directly inside a
   data-table cell (e.g. the Float Expenses editable line table) — same
   tokens as .form-control, just lower-profile so a dense row of inputs
   doesn't read as a stack of separate form fields. Borderless until
   hover/focus keeps the row visually calm; a matched/locked field (e.g. Unit
   auto-filled from a product) still gets the shared [readonly] treatment. */
.table-inline-input {
  min-height: 34px;
  padding: 6px var(--space-2);
  border-color: transparent;
  background: transparent;
  font-size: var(--fs-sm);
}

.table-inline-input:hover {
  background: var(--surface-input);
}

.table-inline-input:focus {
  background: var(--surface-elevated);
  border-color: var(--color-primary);
}

.table-inline-input[readonly] {
  border-color: transparent;
}

.form-control {
  width: 100%;
  min-height: 42px;
  box-sizing: border-box;
  padding: 10px var(--space-3);
  background: var(--surface-input);
  color: var(--color-text);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  line-height: 1.35;
  box-shadow: inset 0 1px 2px rgba(25, 28, 20, 0.05);
  transition: background var(--transition-fast), border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.form-control:hover:not(:disabled):not([readonly]) {
  border-color: var(--field-border-hover);
}

.form-control:focus {
  outline: none;
  border-color: var(--color-secondary-dark);
  box-shadow: var(--shadow-focus);
  background: var(--surface-elevated);
}

.form-control::placeholder {
  color: var(--color-text-faint);
  opacity: 1;
}

textarea.form-control {
  resize: vertical;
  min-height: 90px;
}

select.form-control {
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%236b6a58' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 36px;
}

.form-check {
  display: flex;
  align-items: center;
  gap: 8px;
}

.form-check input[type="checkbox"],
.form-check input[type="radio"] {
  width: 18px;
  height: 18px;
  accent-color: var(--color-secondary);
}

.input-icon {
  position: relative;
}
.input-icon .icon {
  position: absolute;
  left: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-faint);
}
.input-icon .form-control {
  padding-left: 38px;
}

.file-drop {
  position: relative;
  display: block;
  background: var(--surface-input);
  border: 2px dashed var(--field-border);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  text-align: center;
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
.file-drop:hover {
  border-color: var(--color-secondary-dark);
  background: var(--surface-elevated);
}

.file-drop__text {
  margin-top: 8px;
  margin-bottom: 4px;
}

.file-drop__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.file-drop.dragover {
  border-color: var(--color-secondary);
  background: var(--color-secondary-light);
}

.file-drop__preview {
  display: block;
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  margin: 0 auto var(--space-2);
}

/* ---- Branch Selector ---- */
.branch-selector {
  position: relative;
}

.branch-selector__trigger {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 8px var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-default);
  background: var(--surface-input);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  transition: border-color var(--transition-fast), background var(--transition-fast);
}

.branch-selector__trigger:hover {
  border-color: var(--color-secondary);
}

.branch-selector__trigger .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-success);
  flex-shrink: 0;
}

.branch-selector__menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  min-width: 240px;
  background: var(--surface-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-level-3);
  padding: var(--space-2);
  z-index: var(--z-dropdown);
  display: none;
}

.branch-selector__menu.open {
  display: block;
}

.branch-selector__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  transition: background var(--transition-fast);
}

.branch-selector__item:hover {
  background: var(--color-bg);
}

.branch-selector__item.active {
  background: var(--color-secondary-light);
  color: var(--color-primary-dark);
  font-weight: var(--fw-semibold);
}

.branch-selector__item .check {
  color: var(--color-secondary-dark);
  opacity: 0;
}
.branch-selector__item.active .check {
  opacity: 1;
}

/* ---- Generic Dropdown ---- */
.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 200px;
  background: var(--surface-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-level-3);
  padding: var(--space-2);
  z-index: var(--z-dropdown);
  display: none;
}

.dropdown-menu.open {
  display: block;
}

.dropdown-menu.align-left {
  right: auto;
  left: 0;
}

.dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  color: var(--color-text);
  text-align: left;
  transition: background var(--transition-fast);
}

.dropdown-item:hover {
  background: var(--surface-section);
}

.dropdown-item.danger {
  color: var(--color-danger);
}

.dropdown-divider {
  height: 1px;
  background: var(--color-border);
  margin: var(--space-2) 0;
}

.dropdown-header {
  padding: var(--space-2) var(--space-3);
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

/* Topbar global search results — same visual language as .dropdown-menu
   (elevated surface, same shadow/radius) but its own class/open-state,
   deliberately not .dropdown-menu itself, since closeAllFloating()'s
   document-click listener would otherwise fight with the search box's own
   containment-based close logic in app.js. */
.search-results-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  max-height: 420px;
  overflow-y: auto;
  background: var(--surface-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-level-3);
  padding: var(--space-2);
  z-index: var(--z-dropdown);
  display: none;
}

.search-results-menu.open {
  display: block;
}

.search-results-menu__group + .search-results-menu__group {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border-subtle);
}

.search-results-menu__label {
  padding: var(--space-1) var(--space-3);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-muted);
}

.search-results-menu__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 9px var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  color: var(--color-text);
}

.search-results-menu__item:hover {
  background: var(--surface-section);
}

.search-results-menu__subtitle {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

.search-results-menu__empty {
  padding: var(--space-3);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
  text-align: center;
}

/* Product-search combobox used by item-row tables (e.g. the Requisition
   form) — a single shared menu appended to <body> and repositioned via JS
   per active row (position:fixed, not absolute), so it's never clipped by
   a scrolling .table-wrap ancestor the way an absolutely-positioned
   per-row dropdown would be. z-index sits above --z-modal since this
   control always lives inside a modal. */
.product-search-menu {
  position: fixed;
  max-height: 280px;
  overflow-y: auto;
  background: var(--surface-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-level-3);
  padding: var(--space-2);
  z-index: var(--z-modal-popover);
  display: none;
}

.product-search-menu.open {
  display: block;
}

.product-search-menu__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  padding: 9px var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  color: var(--color-text);
  text-align: left;
}

.product-search-menu__item:hover,
.product-search-menu__item.active {
  background: var(--surface-section);
}

.product-search-menu__subtitle {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

.product-search-menu__empty {
  padding: var(--space-3);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
  text-align: center;
}

/* ---- Notification / Message panels ---- */
.notif-panel {
  width: 340px;
  max-height: 420px;
  display: flex;
  flex-direction: column;
}

.notif-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-2) var(--space-3) var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.notif-panel__list {
  overflow-y: auto;
}

.notif-item {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  transition: background var(--transition-fast);
}

.notif-item:hover {
  background: var(--color-bg);
}

.notif-item__icon {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.notif-item__body {
  flex: 1;
  min-width: 0;
}

.notif-item__title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
}

.notif-item__meta {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  margin-top: 2px;
}

.notif-item.unread {
  background: rgba(198, 154, 109, 0.08);
}

/* ---- Tables ---- */
.table-wrap {
  overflow-x: auto;
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-level-1);
}

.card > .table-wrap {
  border: 0;
  border-top: 1px solid var(--border-default);
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  box-shadow: none;
}

/* Dashboard summary-card tables (.panel-grid, e.g. Booking Dashboard's
   Today's Arrivals / Upcoming Events / Unpaid Deposits) are short,
   un-paginated tables with no toolbar/pagination footer beneath them, so
   without this the last row's own border sits flush against the card's
   rounded bottom edge. Full paginated list-table pages keep the plain
   flush .card > .table-wrap above -- their pagination bar already supplies
   that breathing room as a sibling element. */
.panel-grid .card > .table-wrap {
  padding-bottom: var(--space-3);
}

/* Keep table controls visually separate from the data they operate on. */
.card > .card-body.toolbar + .table-wrap,
.card > .card-body:has(> .toolbar) + .table-wrap {
  margin-top: var(--space-3);
  border-top: 1px solid var(--border-default);
}

/* Inline add-row controls need the same breathing room below a table. */
.table-wrap + .btn,
.table-wrap + .btn-group,
.table-wrap + .toolbar {
  margin-top: var(--space-3);
}

/* width:100% (2026-08-23, superseding this same day's own width:auto/
   shrink-to-fit experiment): a table now stretches to fill its card again
   -- a narrow-content table (e.g. Budget vs Actual's 4 columns) left a
   large blank gap otherwise (shrink-to-fit) or, centered, an equally large
   gap just split on both sides -- neither read as "fits the page" the way
   this app wants. table-layout:auto still distributes that width across
   columns roughly proportional to each column's own content, not equally,
   so this is not a return to the ORIGINAL bug (11-column tables like Cash
   and Bank Summary squeezing wide columns down to fit narrow ones) -- that
   bug is independently prevented by the min-width floors already set on
   those specific wide tables (#cash-bank-summary-table,
   #account-statement-table below) and by tbody td's own nowrap default
   just above, both unaffected by this rule. */
.data-table {
  width: 100%;
  font-size: var(--fs-sm);
  background: var(--surface-card);
  border: 0;
}

.data-table thead th {
  text-align: left;
  padding: var(--space-3) var(--space-3);
  background: var(--surface-table-head);
  color: var(--color-text-muted);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
  border-bottom: 1px solid var(--border-default);
  border-right: 1px solid var(--border-subtle);
  position: sticky;
  top: 0;
  z-index: 2;
}

.data-table thead th:last-child {
  border-right: none;
}

.data-table thead th.sortable {
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}

.data-table thead th.sortable:hover {
  color: var(--color-text);
}

.data-table thead th[aria-sort="ascending"]::after {
  content: " ↑";
  color: var(--module-accent);
}

.data-table thead th[aria-sort="descending"]::after {
  content: " ↓";
  color: var(--module-accent);
}

/* nowrap by default, matching thead th (2026-08-23): every column that
   holds a short, atomic value -- reference/ID, technical source-type label,
   person name, branch/section name, status -- was wrapping across 2-3
   lines the moment a table got wide enough to need horizontal scroll,
   purely because table body cells had no white-space rule at all (only
   headers did). .table-wrap's existing overflow-x:auto already handles a
   too-wide table via horizontal scroll, so there was never a real reason
   for body text to wrap instead. The one real exception is genuinely
   long-form free text -- Description/Notes/Remarks/Reason/Purpose-style
   columns, where wrapping is the CORRECT, more readable behavior (reading
   a paragraph via horizontal scroll instead of wrapped lines is worse, not
   better) -- those opt back into wrapping via .cell-wrap on the <td>.

   width:1px (2026-08-29): nowrap alone stops TEXT wrapping across lines,
   but table-layout:auto can still squeeze a COLUMN narrower than its own
   content's natural width once a wide table's columns collectively exceed
   the available space -- content then either wraps anyway (if anything
   ever resets white-space back to normal for it) or, worse, silently
   overflows/gets clipped inside a now-too-narrow cell. This was previously
   patched per-table with explicit min-width floors (#cash-bank-summary-
   table, #account-statement-table, and others -- left in place, now
   redundant but harmless) rather than fixed everywhere at once. width:1px
   is the standard shrink-to-fit hint: table-layout:auto never actually
   renders a column at literally 1px when it holds nowrap content -- it
   still allocates that column's own min-content (full unwrapped) width
   first, and only THEN grows whichever column(s) don't carry this hint
   (.cell-wrap/.hr-reason-cell below) to soak up whatever's left of the
   table's own 100% width. Net effect: every short-value column now always
   expands to fit its own content instead of ever being squeezed, while the
   one genuinely free-text column per table keeps absorbing the remainder
   and wrapping, and the table as a whole still fills the page (no return
   to this same file's own already-reverted width:auto/shrink-the-whole-
   table experiment, see .data-table itself above). */
.data-table tbody td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
  border-right: 1px solid var(--border-subtle);
  vertical-align: middle;
  white-space: nowrap;
  width: 1px;
}

.data-table tbody td.cell-wrap {
  white-space: normal;
  width: auto;
}

/* width:auto (2026-08-29): a colspan cell (the "No records found"/"Could
   not load..." empty-state row every table renders this way) is never one
   column's content -- it deliberately spans every column at once. Without
   this, tbody td's own new width:1px shrink-to-fit hint above would still
   apply to it, and since an empty table's placeholder row is often the
   ONLY row present (nothing else left to define real column widths from),
   the whole table would collapse down to a sliver instead of staying at
   its normal 100% width. */
.data-table tbody td[colspan] {
  width: auto;
}

.data-table tbody td:last-child {
  border-right: none;
}

/* Total/footer row (2026-08-22): tbody td's own padding/border/vertical-
   align rule above never applied here (different selector), so a tfoot row
   silently fell back to the browser's bare UA-default cell box -- same
   column grid (one <table>, so verticals were never actually misaligned),
   but visibly tighter padding, no vertical centering, and no border-right
   dividers, making the total row look like a different table glued on
   underneath. Mirrors tbody's own box model exactly, plus a top rule to
   read as the totals separator every accounting-style report uses. */
.data-table tfoot td {
  padding: var(--space-3);
  border-top: 2px solid var(--border-default);
  border-right: 1px solid var(--border-subtle);
  vertical-align: middle;
}

.data-table tfoot td:last-child {
  border-right: none;
}

.data-table tbody tr {
  transition: background var(--transition-fast);
}

.data-table tbody tr:hover {
  background: var(--module-accent-soft);
}

.data-table tbody tr:nth-child(even) {
  background: color-mix(in srgb, var(--surface-section) 72%, transparent);
}

.data-table tbody tr:nth-child(even):hover {
  background: var(--module-accent-soft);
}

.data-table[data-sticky-first="true"] th:first-child,
.data-table[data-sticky-first="true"] td:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--surface-card);
  box-shadow: 1px 0 0 var(--border-default);
}

.data-table[data-sticky-first="true"] thead th:first-child {
  z-index: 3;
  background: var(--surface-table-head);
}

.data-table[data-density="compact"] thead th,
.data-table[data-density="compact"] tbody td,
.data-table[data-density="compact"] tfoot td {
  padding: var(--space-2) var(--space-3);
}

.data-table[data-density="comfortable"] thead th,
.data-table[data-density="comfortable"] tbody td,
.data-table[data-density="comfortable"] tfoot td {
  padding: var(--space-4);
}

.table-resize-handle {
  position: absolute;
  top: 0;
  right: -2px;
  width: 5px;
  height: 100%;
  cursor: col-resize;
  touch-action: none;
  z-index: 4;
}

.table-resize-handle:hover,
.table-resize-handle.is-resizing {
  background: var(--module-accent);
}

.enterprise-table-tools {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border-default);
  background: var(--surface-section);
}

.toolbar .enterprise-table-tools {
  min-height: auto;
  padding: 0;
  margin-left: auto;
  border: 0;
  background: transparent;
}

.column-visibility-menu {
  max-height: min(360px, 60vh);
  overflow-y: auto;
}

.column-visibility-menu label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  cursor: pointer;
}

.column-visibility-menu label:hover {
  background: var(--surface-section);
}

.data-table tbody tr:last-child td {
  border-bottom: none;
}

.data-table .cell-media {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.data-table .thumb {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
}

.data-table .cell-primary {
  font-weight: var(--fw-semibold);
}

.data-table .cell-muted {
  color: var(--color-text-muted);
}

.row-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  justify-content: center;
  min-width: 76px;
}

.data-table th.action-column,
.data-table td.action-column {
  min-width: 128px;
  width: 128px;
  text-align: center;
  visibility: visible;
}

.data-table thead th.text-right,
.data-table tbody td.text-right,
.data-table tfoot td.text-right {
  text-align: right;
}

.data-table thead th.text-center,
.data-table tbody td.text-center,
.data-table tfoot td.text-center {
  text-align: center;
}

.data-table tbody td.text-right .row-actions,
.data-table tbody td.text-center .row-actions {
  justify-content: center;
}

.data-table tbody td:has(> .btn-icon:only-child) {
  text-align: center;
}

.data-table td.action-column .btn-icon,
.row-actions .btn-icon {
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
  opacity: 1;
  visibility: visible;
}

/* ---- Toolbar / Filters ---- */
.toolbar {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-3);
  flex-wrap: wrap;
  width: 100%;
  margin-bottom: 0;
}

.main-content > .toolbar,
.main-content > .section > .toolbar {
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  background: var(--surface-section);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-level-1);
}

.card-body:has(> .toolbar) {
  background: var(--surface-section);
}

.toolbar-search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 240px;
  min-width: 200px;
  max-width: 400px;
  height: 42px;
}

.toolbar-search .form-control {
  height: 100%;
  padding-left: 38px;
}

.toolbar-search .icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-faint);
}

.toolbar-filter {
  /* .form-control sets width:100%, which (unlike .toolbar-search's input,
     constrained by its own wrapper) resolves against the whole toolbar row
     here since these selects are direct flex children — forcing each onto
     its own line. Override so they size like normal inline filter controls. */
  width: auto;
  height: 42px;
  flex: 0 1 240px;
  min-width: 190px;
}

.toolbar > .form-control:not(.toolbar-filter),
.toolbar .date-range-group .form-control {
  height: 42px;
}

.toolbar > .btn,
.toolbar .date-range-group .btn {
  min-height: 42px;
}

.toolbar-spacer {
  flex: 1;
}

.calendar-period-label {
  min-width: 220px;
  text-align: center;
}

.control-w-220 { max-width: 220px; }
.control-w-260 { max-width: 260px; }

.toolbar-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 42px;
  flex: 0 0 auto;
  padding: 0 var(--space-3);
  background: var(--surface-input);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  color: var(--color-text);
  cursor: pointer;
  white-space: nowrap;
}

.toolbar-toggle input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin: 0;
  cursor: pointer;
}

.filter-chip-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}

.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: var(--radius-full);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

.filter-chip button {
  color: var(--color-text-faint);
  display: inline-flex;
}

/* ---- Pagination ---- */
.pagination-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3);
  flex-wrap: wrap;
  border-top: 1px solid var(--color-border);
}

.pagination-info {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

.pagination {
  display: flex;
  align-items: center;
  gap: 4px;
}

.pagination-btn {
  min-width: 32px;
  height: 32px;
  padding: 0 8px;
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
  transition: background var(--transition-fast), color var(--transition-fast);
}

.pagination-btn:hover {
  background: var(--color-bg);
  color: var(--color-text);
}

.pagination-btn.active {
  background: var(--color-primary);
  color: #fff;
}

.pagination-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ---- Tabs ---- */
.tabs {
  display: flex;
  gap: var(--space-2);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-4);
  overflow-x: auto;
}

.tab-btn {
  padding: var(--space-3) var(--space-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--color-text-muted);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: color var(--transition-fast), border-color var(--transition-fast);
}

.tab-btn:hover {
  color: var(--color-text);
}

.tab-btn.active {
  color: var(--module-accent);
  border-bottom-color: var(--module-accent);
}

.tab-panel {
  display: none;
}

.tab-panel.active {
  display: block;
}

/* ---- Accordion ---- */
.accordion-item {
  background: var(--surface-section);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-2);
  overflow: hidden;
}

.accordion-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: var(--space-3) var(--space-4);
  font-weight: var(--fw-medium);
  font-size: var(--fs-sm);
  background: var(--surface-section);
}

.accordion-header .icon {
  transition: transform var(--transition-fast);
}

.accordion-item.open .accordion-header .icon {
  transform: rotate(180deg);
}

.accordion-body {
  max-height: 0;
  overflow: hidden;
  transition: max-height var(--transition);
}

.accordion-body__inner {
  padding: 0 var(--space-4) var(--space-4);
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
}

/* ---- Modals ---- */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: var(--surface-overlay);
  z-index: var(--z-modal-backdrop);
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
}

.modal-backdrop.open {
  display: flex;
  animation: backdrop-in var(--transition-fast);
}

@keyframes backdrop-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.modal {
  background: var(--surface-modal);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-level-3);
  width: 100%;
  max-width: 560px;
  max-height: 90vh;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  overflow: hidden;
  z-index: var(--z-modal);
}

/* A <form> wrapping modal-body + modal-footer would otherwise be an
   unconstrained grid item that grows to fit all its content; making it
   a transparent layout box lets its children join the modal's own grid
   rows directly (header / scrollable body / pinned footer). */
.modal > form {
  display: contents;
}

.modal.modal-lg { max-width: 760px; }
.modal.modal-sm { max-width: 420px; }
.modal.modal-xl { max-width: 960px; }

/* Goods Received Note workspace — wider than the standard .modal-xl so its
   dense receiving table (13 columns) needs less internal horizontal scroll;
   the table itself still sits in the usual .table-wrap (overflow-x: auto)
   for narrower viewports. */
.modal.grn-workspace { max-width: 1280px; }
.modal.grn-workspace .modal-footer { flex-wrap: wrap; }

/* Purchase Requisition form — wider than the standard .modal-xl so the
   per-line Preferred Supplier / Notes text inputs (added alongside Current
   Stock once suppliers moved from one header field to per-line) have real
   typing room instead of being squeezed by the Product/Unit/Qty columns. */
.modal.requisition-form-workspace { max-width: 1180px; }

/* Bulk Stock Cleanup can list every product in a branch -- caps the table at
   a fixed height so the modal itself doesn't grow past the viewport. */
.bulk-stock-table-wrap { max-height: 22rem; overflow-y: auto; }

/* Requisition -> PO -> GRN -> Invoice -> Posted progress strip, shown at the
   top of the Purchase Order detail workspace. */
.po-progress-strip {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-section);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
}

.po-progress-strip__step {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
  white-space: nowrap;
}

.po-progress-strip__dot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  font-size: var(--fs-xs);
  font-weight: 600;
  flex-shrink: 0;
}

.po-progress-strip__step.is-done .po-progress-strip__dot {
  background: var(--color-success);
  border-color: var(--color-success);
  color: var(--color-text-on-primary);
}

.po-progress-strip__step.is-done { color: var(--color-text); }

.po-progress-strip__step.is-active .po-progress-strip__dot {
  border-color: var(--color-secondary);
  color: var(--color-secondary);
}

.po-progress-strip__step.is-active { color: var(--color-text); font-weight: 600; }

.po-progress-strip__connector {
  flex: 1 1 16px;
  min-width: 12px;
  height: 1px;
  background: var(--color-border);
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  color: var(--color-text-on-primary);
  background: var(--color-primary);
  border-bottom: 1px solid var(--color-primary-dark);
}

.modal-header h1,
.modal-header h2,
.modal-header h3 {
  color: var(--color-text-on-primary);
  font-size: var(--fs-md);
}

.modal-close {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  color: rgba(255, 255, 255, 0.78);
}

.modal-close:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}

/* Purchase Order / Invoice detail modal — brand-colored header, matching the
   command banner used on the Purchases/Supplier Ledger pages. Shared markup
   across every page that includes #purchase-detail-modal. */
#purchase-detail-modal .modal-header {
  background: var(--color-primary);
  border-bottom-color: var(--color-primary);
}

#purchase-detail-modal .modal-header h3 {
  color: #fff;
}

#purchase-detail-modal .modal-close {
  color: rgba(255, 255, 255, .72);
}

#purchase-detail-modal .modal-close:hover {
  background: rgba(255, 255, 255, .12);
  color: #fff;
}

.modal-body {
  padding: var(--space-5);
  overflow-y: auto;
  min-height: 0;
  background: var(--surface-card);
}

.modal-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  background: var(--surface-section);
  border-top: 1px solid var(--border-default);
  flex-wrap: wrap;
}

.modal-footer.space-between {
  justify-content: space-between;
}

/* ---- Alerts ---- */
.alert {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--fs-sm);
  border: 1px solid transparent;
}

.alert .icon {
  flex-shrink: 0;
}

.alert-success { background: var(--color-success-bg); color: var(--color-success); border-color: rgba(21,128,61,0.25); }
.alert-warning { background: var(--color-warning-bg); color: var(--color-warning); border-color: rgba(217,119,6,0.25); }
.alert-danger { background: var(--color-danger-bg); color: var(--color-danger); border-color: rgba(220,38,38,0.25); }
.alert-info { background: var(--color-info-bg); color: var(--color-info); border-color: rgba(37,99,235,0.25); }

/* ---- Toast Notifications ---- */
.toast-stack {
  position: fixed;
  bottom: var(--space-4);
  right: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  z-index: var(--z-toast);
  max-width: 340px;
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--surface-dialog);
  border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-level-3);
  font-size: var(--fs-sm);
  animation: toast-in 0.25s ease;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateX(30px); }
  to { opacity: 1; transform: translateX(0); }
}

.toast .icon {
  flex-shrink: 0;
  margin-top: 2px;
}

.toast.success .icon { color: var(--color-success); }
.toast.warning .icon { color: var(--color-warning); }
.toast.danger .icon { color: var(--color-danger); }
.toast.info .icon { color: var(--color-info); }

.toast-close {
  margin-left: auto;
  color: var(--color-text-faint);
}

/* ---- Tooltip ---- */
[data-tooltip] {
  position: relative;
}

[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--color-primary-dark);
  color: #fff;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  font-size: var(--fs-xs);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition-fast);
  z-index: var(--z-tooltip);
}

[data-tooltip]:hover::after {
  opacity: 1;
}

/* ---- Loading Spinner ---- */
.spinner {
  width: 20px;
  height: 20px;
  border: 2.5px solid var(--color-border);
  border-top-color: var(--color-secondary);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

.spinner-lg {
  width: 40px;
  height: 40px;
  border-width: 3.5px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.loading-overlay {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-7);
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
}

/* ---- Empty State ---- */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-7) var(--space-4);
  color: var(--color-text-muted);
  /* white-space is inherited -- a .data-table tbody td's own new nowrap
     default (2026-08-23) would otherwise cascade into every "Could not
     load..."/"No records found" message rendered here, since this always
     sits inside a colspan <td>. Reset once at this boundary rather than on
     every individual descendant. */
  white-space: normal;
}

.empty-state__icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--surface-section);
  border: 1px solid var(--border-default);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-3);
  color: var(--module-accent);
}

.empty-state h3 {
  color: var(--color-text);
  margin-bottom: 4px;
  font-size: var(--fs-base);
}

.empty-state p {
  font-size: var(--fs-sm);
  max-width: 320px;
  margin-bottom: var(--space-3);
}

/* ---- Chart Containers ---- */
.chart-card {
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-level-1);
  overflow: hidden;
}

.chart-card::before {
  content: "";
  display: block;
  height: 3px;
  background: var(--module-accent);
}

/* ---- Loading skeletons ---- */
.skeleton {
  display: block;
  min-height: 12px;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--color-control-bg) 25%, var(--color-card) 50%, var(--color-control-bg) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.2s ease-in-out infinite;
}

.loading-skeleton {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-4);
}

.skeleton-text { height: 12px; }
.skeleton-title { width: 55%; height: 20px; }
.skeleton-card { min-height: 112px; }

@keyframes skeleton-shimmer {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

.chart-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: var(--space-4);
  margin-bottom: 0;
  background: var(--surface-section);
  border-bottom: 1px solid var(--border-default);
  gap: var(--space-2);
  flex-wrap: wrap;
}

.chart-card__header h3 {
  font-size: var(--fs-sm);
}

.chart-card__header p {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

.chart-canvas-wrap {
  position: relative;
  height: 260px;
  width: calc(100% - var(--space-8));
  margin: var(--space-4);
}

.chart-canvas-wrap canvas {
  animation: chart-reveal var(--transition-slow);
}

@keyframes chart-reveal {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

.chart-legend {
  padding: 0 var(--space-4) var(--space-4);
}

.chart-canvas-wrap.sm { height: 180px; }
.chart-canvas-wrap.lg { height: 340px; }

/* ---- Chart empty / failed-to-load state (charts.js renderEmptyChart()) ---- */
.chart-empty-state {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: var(--space-2);
  padding: var(--space-4);
  color: var(--color-text-muted);
}

.chart-empty-state__icon {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--surface-section);
  border: 1px solid var(--border-default);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--module-accent);
}

.chart-empty-state__icon svg {
  width: 18px;
  height: 18px;
}

.chart-empty-state p {
  font-size: var(--fs-sm);
  max-width: 260px;
  margin: 0;
}

.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-3);
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

.chart-legend__item {
  display: flex;
  align-items: center;
  gap: 6px;
}

.chart-legend__dot {
  width: 9px;
  height: 9px;
  border-radius: var(--radius-sm);
}

/* ---- Chart negative-value footnote (charts.js renderNegativeCategoryNote(),
   UI-D1) -- sits below a chart's canvas, never as an overlay, so it can
   coexist with real positive bars still drawn above it. ---- */
.chart-negative-note {
  padding: 0 var(--space-4) var(--space-4);
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

.chart-negative-note__heading {
  margin: 0 0 var(--space-2);
  font-weight: 600;
  color: var(--color-danger);
}

.chart-negative-note__item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 2px 0;
}

.chart-negative-note__label {
  color: var(--color-text-muted);
}

.chart-negative-note__value {
  font-weight: 600;
  color: var(--color-danger);
  white-space: nowrap;
}

/* ---- Progress bar ---- */
.progress {
  width: 100%;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--color-bg);
  overflow: hidden;
}

.progress__bar {
  height: 100%;
  border-radius: var(--radius-full);
  background: var(--color-secondary);
  transition: width var(--transition-slow);
}

.progress__bar.success { background: var(--color-success); }
.progress__bar.warning { background: var(--color-warning); }
.progress__bar.danger { background: var(--color-danger); }

/* ---- Timeline ---- */
.timeline {
  position: relative;
  padding-left: var(--space-5);
}

.timeline::before {
  content: "";
  position: absolute;
  left: 9px;
  top: 4px;
  bottom: 4px;
  width: 2px;
  background: var(--color-border);
}

.timeline-item {
  position: relative;
  padding-bottom: var(--space-4);
}

.timeline-item:last-child {
  padding-bottom: 0;
}

.timeline-item::before {
  content: "";
  position: absolute;
  left: calc(-1 * var(--space-5) + 4px);
  top: 4px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-secondary);
  border: 2px solid var(--color-card);
  box-shadow: 0 0 0 2px var(--color-secondary);
}

.timeline-item__meta {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  margin-bottom: 2px;
}

.timeline-item__title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.timeline-item__title-text {
  min-width: 0;
}

/* ---- List items (activity, low-stock, etc.) ---- */
.list-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}

.list-item:last-child {
  border-bottom: none;
}

.list-item__icon {
  width: 38px;
  height: 38px;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.list-item__body {
  flex: 1;
  min-width: 0;
}

.list-item__title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
}

.list-item__meta {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  margin-top: 2px;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.list-item__value {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-align: right;
  flex-shrink: 0;
}

/* ---- Avatar ---- */
.avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: #fff;
  background: var(--color-secondary-dark);
  flex-shrink: 0;
}

.avatar-sm { width: 28px; height: 28px; font-size: 0.625rem; }
.avatar-lg { width: 56px; height: 56px; font-size: var(--fs-base); }

.profile-thumb {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  flex-shrink: 0;
}

.avatar-group {
  display: flex;
}
.avatar-group .avatar {
  margin-left: -10px;
  border: 2px solid var(--color-card);
}
.avatar-group .avatar:first-child {
  margin-left: 0;
}

/* ---- Theme toggle switch ---- */
.theme-toggle {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.theme-toggle:hover {
  background: var(--color-bg);
  color: var(--color-text);
}

.switch {
  position: relative;
  display: inline-block;
  width: 42px;
  height: 24px;
  flex-shrink: 0;
}
.switch input { display: none; }
.switch .track {
  position: absolute;
  inset: 0;
  background: var(--color-border-strong);
  border-radius: var(--radius-full);
  transition: background var(--transition-fast);
}
.switch .track::before {
  content: "";
  position: absolute;
  width: 18px;
  height: 18px;
  left: 3px;
  top: 3px;
  border-radius: 50%;
  background: #fff;
  transition: transform var(--transition-fast);
  box-shadow: var(--shadow-sm);
}
.switch input:checked + .track {
  background: var(--color-secondary);
}
.switch input:checked + .track::before {
  transform: translateX(18px);
}

/* ---- Inline-form / mini-table utility classes ---- */
.section-title.compact h2 { font-size: var(--fs-base); }
.mt-2 { margin-top: var(--space-2); }
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }
.mt-5 { margin-top: var(--space-5); }

/* "Payment" section header inside the Purchase Order / Invoice detail modal —
   brand-colored band matching the modal's own header, instead of a plain
   heading butted up against the product table. */
.payment-section-title {
  padding: var(--space-2) var(--space-3);
  background: var(--color-primary);
  border-radius: var(--radius-sm);
}

.payment-section-title h2 {
  color: #fff;
}

/* Read-only "here's the line you're acting on" summary card at the top of
   the Float Expenses Convert/Keep-as-Expense modals — a tinted, bordered box
   instead of plain floating label/value text, so the line being converted or
   classified reads as a distinct, anchored reference point. */
.float-line-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-section);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-4);
}

.float-line-summary__amount {
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  color: var(--color-primary);
}

/* Small non-colored section labels breaking a long form into scannable
   groups (Purchase Details / Product / Quantity & Pricing / Attachment) —
   lighter-weight than .payment-section-title's brand band, which would be
   too heavy repeated four times in one modal. */
.form-section-label {
  margin: var(--space-4) 0 var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--surface-section);
  border: 1px solid var(--border-default);
  border-left: 3px solid var(--module-accent);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: .05em;
  text-transform: uppercase;
}

fieldset.form-section {
  min-width: 0;
}

fieldset.form-section > legend {
  padding: 0 var(--space-2);
  color: var(--color-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}

.form-section-label:first-child {
  margin-top: 0;
}

.col-qty { width: 90px; min-width: 70px; }
.col-cost { width: 120px; min-width: 90px; }
.col-total { width: 110px; min-width: 90px; }
.col-action { width: 40px; min-width: 40px; }
.col-share { width: 160px; }

.payroll-lines-table { min-width: 1040px; }
.payroll-lines-table .form-control { min-width: 100px; }
.payroll-lines-table .js-line-employee { min-width: 220px; }
.payroll-lines-table .js-line-description { min-width: 170px; }
.payroll-lines-table input[type="number"] { text-align: right; }
.payroll-lines-table .js-line-net { white-space: nowrap; }
.payroll-lines-table .payroll-line-invalid .js-line-net { color: var(--color-danger); }

.payroll-totals {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-6);
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}

.payroll-totals > div {
  display: grid;
  flex: 1 1 130px;
  gap: var(--space-1);
  min-width: 130px;
  text-align: right;
}

.payroll-totals span {
  color: var(--color-text-muted);
  font-size: var(--fs-xs);
}

.payroll-totals__net strong { font-size: var(--fs-lg); }

/* Item-row table inside the New Purchase Order modal: force a real minimum
   table width so table-layout:auto can't crush the Qty/Cost inputs down to
   a width narrower than their own padding (which makes typed values invisible
   even though the value is there) — the .table-wrap already scrolls this. */
.purchase-items-table {
  min-width: 520px;
}

.purchase-items-table .js-item-qty,
.purchase-items-table .js-item-cost,
.purchase-items-table .js-req-item-qty,
.purchase-items-table .js-req-item-price,
.js-convert-qty,
.js-convert-price {
  padding-left: var(--space-2);
  padding-right: var(--space-2);
  text-align: center;
}

/* Requisition item rows have more columns than the plain Purchase Order item
   table (product, current stock, unit, qty, preferred supplier, notes), so
   they need more horizontal room before .table-wrap's scroll kicks in --
   paired with .modal.requisition-form-workspace's wider modal above so the
   Product/Preferred Supplier/Notes text inputs aren't squeezed down to
   unusable widths by table-layout:auto. */
.requisition-items-table {
  min-width: 940px;
}

.requisition-items-table .col-product { width: 220px; min-width: 180px; }
.requisition-items-table .col-stock { width: 120px; min-width: 100px; }
.requisition-items-table .col-unit { width: 80px; min-width: 60px; }
.requisition-items-table .col-supplier { width: 220px; min-width: 180px; }
.requisition-items-table .col-notes { width: 180px; min-width: 140px; }

/* These item-entry tables sit right above a modal/card footer's Save-Cancel
   row, with nothing else to visually close them off — the default 1px
   var(--border-default) .table-wrap border is too low-contrast against a
   white modal body to read as a closing edge, so the table appears to trail
   off into blank space. A heavier, darker bottom border fixes that. */
.table-wrap:has(> .purchase-items-table) {
  border-bottom: 2px solid var(--border-strong);
  /* .table-wrap is the overflow-x:auto scroller, so this padding lands
     inside the scrollable viewport, below the table's last row — the
     horizontal scrollbar always docks at the very bottom of that viewport,
     so the padding is what pushes it down off the row instead of sitting
     flush against it. */
  padding-bottom: var(--space-2);
}
.total-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}
.total-row .value { font-size: var(--fs-lg); }

.purchase-action-panel {
  margin-top: var(--space-4);
  padding: var(--space-4);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.purchase-action-panel .form-group {
  margin-bottom: 0;
  margin-top: 0;
}

.purchase-action-panel .form-group + .purchase-action-panel__buttons {
  margin-top: var(--space-3);
}

.purchase-action-panel__buttons {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* purchaseWorkflowFooterButtonsHtml() (purchase-payments.js) concatenates
   several buttons (Cancel/Reject, Complete Pricing, Create GRN, Review/View
   Supplier Invoice) into this one span with no separator between them --
   .modal-footer's own gap only applies between ITS direct flex children
   (this span is one item, Close/Print/Pay Invoice are the others), not
   between the buttons packed inside it. inline-flex (not flex) keeps it
   sitting inline alongside those other footer buttons instead of forcing
   them onto their own row. */
#purchase-detail-workflow-action {
  display: inline-flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* Same fix as #purchase-detail-workflow-action above, for
   requisitionDetailActionsHtml()'s (purchase-requisitions.js) own
   concatenated Approve/Return for Correction/Reject/Cancel buttons. */
#requisition-detail-actions {
  display: inline-flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* ---- Utility ---- */
.text-muted { color: var(--color-text-muted); }
.text-faint { color: var(--color-text-faint); }
.text-success { color: var(--color-success); }
.text-warning { color: var(--color-warning); }
.text-danger { color: var(--color-danger); }
.text-info { color: var(--color-info); }
.text-right { text-align: right; }
.text-center { text-align: center; }
.fw-semibold { font-weight: var(--fw-semibold); }
.fs-xs { font-size: var(--fs-xs); }
.fs-sm { font-size: var(--fs-sm); }
.flex { display: flex; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: var(--space-1); }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.mb-1 { margin-bottom: var(--space-1); }
.mb-2 { margin-bottom: var(--space-2); }
.mb-3 { margin-bottom: var(--space-3); }
.mb-4 { margin-bottom: var(--space-4); }
.mb-0 { margin-bottom: 0; }
.pb-0 { padding-bottom: 0; }
.w-full { width: 100%; }
.hidden { display: none !important; }
.text-nowrap { white-space: nowrap; }

/* ---- Workspace sticky action bar (Multi-Supplier GRN/Invoice Workspaces) ----
   Sits inside .main-content's own flow (not fixed to the viewport), so it
   never fights the .app-shell grid or responsive.css's sidebar breakpoints
   -- it simply sticks to the bottom of the scrollable content column once
   the supplier panels above it are taller than the viewport, same
   `position: sticky` approach .settings-nav already uses at the top of its
   own column. */
.workspace-action-bar {
  position: -webkit-sticky;
  position: sticky;
  bottom: var(--space-3);
  z-index: var(--z-dropdown);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-level-3);
}

.workspace-action-bar__summary {
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}

.workspace-action-bar__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.workspace-batch-result-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-2);
}
