/*
 * zui-components.css — canonical P0 components for the mantra-v4
 * design system. Mirrors what Axelit ships, scaled down to the
 * variants we actually use.
 *
 * Load order:
 *   1. zui-tokens.css      ← CSS variables (typography, spacing, colour)
 *   2. zui-theme.css       ← base theme (existing — Axelit-derived)
 *   3. zui-components.css  ← this file (P0 set)
 *   4. overrides.css       ← page-specific tweaks (rare)
 *
 * Both surfaces load identical content:
 *   CI4 admin: <link href="/assets/zui/zui-components.css">
 *   PWA:       import './css/zui-components.css' from main.js
 *
 * Reference: CI4-migration/design-system/{02-full-visual-audit.md,03-component-coverage-matrix.md}
 */

/* ════════════════════════════════════════════════════════════════
 *  1. BUTTONS
 *  3 sizes × 6 colours × 3 modifiers (solid / outline / soft) = 54 buttons.
 *  Naming: .zui-btn (default md) / .zui-btn-sm / .zui-btn-lg
 *           .zui-btn-{primary,secondary,success,danger,warning,info,neutral}
 *           .zui-btn-outline-{colour} for hollow
 *           .zui-btn-soft-{colour} for tinted background
 *           .zui-btn-icon for icon-only square
 *           .zui-btn-block for full-width
 * ════════════════════════════════════════════════════════════════ */

.zui-btn {
  /* Default = "md" */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--zui-space-2);
  height: var(--zui-btn-h);
  padding: 0 var(--zui-btn-px);
  font-family: var(--zui-font-family);
  font-size: var(--zui-btn-fs);
  font-weight: var(--zui-font-semibold);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  border: 1px solid transparent;
  border-radius: var(--zui-radius);
  cursor: pointer;
  user-select: none;
  transition: background var(--zui-transition), border-color var(--zui-transition), color var(--zui-transition), box-shadow var(--zui-transition);
  background: rgb(var(--gray-100));
  color: rgb(var(--gray-900));
}
.zui-btn:hover  { background: rgb(var(--gray-200)); }
.zui-btn:active { transform: translateY(1px); }
.zui-btn:focus-visible { outline: none; box-shadow: var(--zui-focus-ring); }
.zui-btn:disabled,
.zui-btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

.zui-btn-sm { height: var(--zui-btn-sm-h); padding: 0 var(--zui-btn-sm-px); font-size: var(--zui-btn-sm-fs); gap: var(--zui-space-1); }
.zui-btn-lg { height: var(--zui-btn-lg-h); padding: 0 var(--zui-btn-lg-px); font-size: var(--zui-btn-lg-fs); gap: var(--zui-space-3); }

.zui-btn-block  { width: 100%; }
.zui-btn-pill   { border-radius: var(--zui-radius-pill); }

/* Icon-only square (overrides padding + makes width = height). */
.zui-btn-icon    { width: var(--zui-btn-icon-md); padding: 0; }
.zui-btn-icon.zui-btn-sm { width: var(--zui-btn-icon-sm); }
.zui-btn-icon.zui-btn-lg { width: var(--zui-btn-icon-lg); }

/* Icon inside any button — render at correct size. */
.zui-btn > .material-icons,
.zui-btn > .ti,
.zui-btn > i { font-size: 1.2em; line-height: 1; }

/* ── Solid colour variants ─────────────────────────────────────── */
.zui-btn-primary   { background: rgb(var(--primary));   color: #fff; border-color: rgb(var(--primary));   }
.zui-btn-secondary { background: rgb(var(--secondary)); color: #1e293b; border-color: rgb(var(--secondary)); }
.zui-btn-success   { background: rgb(var(--success));   color: #fff; border-color: rgb(var(--success));   }
.zui-btn-danger    { background: rgb(var(--danger));    color: #fff; border-color: rgb(var(--danger));    }
.zui-btn-warning   { background: rgb(var(--warning));   color: #fff; border-color: rgb(var(--warning));   }
.zui-btn-info      { background: rgb(var(--info));      color: #fff; border-color: rgb(var(--info));      }
.zui-btn-neutral   { background: rgb(var(--gray-800));  color: #fff; border-color: rgb(var(--gray-800));  }

.zui-btn-primary:hover   { background: rgba(var(--primary), 0.9);   border-color: rgba(var(--primary), 0.9);   }
.zui-btn-secondary:hover { background: rgba(var(--secondary), 0.9); border-color: rgba(var(--secondary), 0.9); }
.zui-btn-success:hover   { background: rgba(var(--success), 0.9);   border-color: rgba(var(--success), 0.9);   }
.zui-btn-danger:hover    { background: rgba(var(--danger), 0.9);    border-color: rgba(var(--danger), 0.9);    }
.zui-btn-warning:hover   { background: rgba(var(--warning), 0.9);   border-color: rgba(var(--warning), 0.9);   }
.zui-btn-info:hover      { background: rgba(var(--info), 0.9);      border-color: rgba(var(--info), 0.9);      }
.zui-btn-neutral:hover   { background: rgb(var(--gray-700));        border-color: rgb(var(--gray-700));        }

/* ── Outline variants ──────────────────────────────────────────── */
.zui-btn-outline-primary   { background: transparent; color: rgb(var(--primary));   border-color: rgb(var(--primary));   }
.zui-btn-outline-secondary { background: transparent; color: rgb(var(--secondary)); border-color: rgb(var(--secondary)); }
.zui-btn-outline-success   { background: transparent; color: rgb(var(--success));   border-color: rgb(var(--success));   }
.zui-btn-outline-danger    { background: transparent; color: rgb(var(--danger));    border-color: rgb(var(--danger));    }
.zui-btn-outline-warning   { background: transparent; color: rgb(var(--warning));   border-color: rgb(var(--warning));   }
.zui-btn-outline-info      { background: transparent; color: rgb(var(--info));      border-color: rgb(var(--info));      }
.zui-btn-outline-neutral   { background: transparent; color: rgb(var(--gray-800));  border-color: rgb(var(--gray-300));  }

.zui-btn-outline-primary:hover   { background: rgba(var(--primary), 0.1);   }
.zui-btn-outline-secondary:hover { background: rgba(var(--secondary), 0.1); }
.zui-btn-outline-success:hover   { background: rgba(var(--success), 0.1);   }
.zui-btn-outline-danger:hover    { background: rgba(var(--danger), 0.1);    }
.zui-btn-outline-warning:hover   { background: rgba(var(--warning), 0.1);   }
.zui-btn-outline-info:hover      { background: rgba(var(--info), 0.1);      }
.zui-btn-outline-neutral:hover   { background: rgb(var(--gray-100));        }

/* ── Soft (tinted) variants — light background, full-text colour ─ */
.zui-btn-soft-primary   { background: rgba(var(--primary), 0.12);   color: rgb(var(--primary));   border-color: transparent; }
.zui-btn-soft-secondary { background: rgba(var(--secondary), 0.18); color: rgb(var(--gray-900));  border-color: transparent; }
.zui-btn-soft-success   { background: rgba(var(--success), 0.14);   color: rgb(var(--success));   border-color: transparent; }
.zui-btn-soft-danger    { background: rgba(var(--danger), 0.10);    color: rgb(var(--danger));    border-color: transparent; }
.zui-btn-soft-warning   { background: rgba(var(--warning), 0.14);   color: rgb(var(--warning));   border-color: transparent; }
.zui-btn-soft-info      { background: rgba(var(--info), 0.14);      color: rgb(var(--info));      border-color: transparent; }
.zui-btn-soft-neutral   { background: rgb(var(--gray-100));         color: rgb(var(--gray-700));  border-color: transparent; }

.zui-btn-soft-primary:hover   { background: rgba(var(--primary), 0.20);   }
.zui-btn-soft-secondary:hover { background: rgba(var(--secondary), 0.28); }
.zui-btn-soft-success:hover   { background: rgba(var(--success), 0.22);   }
.zui-btn-soft-danger:hover    { background: rgba(var(--danger), 0.18);    }
.zui-btn-soft-warning:hover   { background: rgba(var(--warning), 0.22);   }
.zui-btn-soft-info:hover      { background: rgba(var(--info), 0.22);      }
.zui-btn-soft-neutral:hover   { background: rgb(var(--gray-200));         }

/* Ghost button — no border, no background, just hover tint. */
.zui-btn-ghost {
  background: transparent;
  color: rgb(var(--gray-700));
  border-color: transparent;
}
.zui-btn-ghost:hover { background: rgb(var(--gray-100)); }


/* ════════════════════════════════════════════════════════════════
 *  2. DROPDOWN (row action menu — the gap user flagged)
 *  Triggered by .zui-dropdown:focus-within or .zui-dropdown.is-open.
 *  Click-to-open requires 1 line of JS:
 *      el.addEventListener('click', () => el.classList.toggle('is-open'))
 * ════════════════════════════════════════════════════════════════ */

.zui-dropdown {
  position: relative;
  display: inline-block;
}

.zui-dropdown-toggle {
  /* Use a zui-btn class (e.g. .zui-btn .zui-btn-ghost .zui-btn-icon) for chrome.
     This class only sets the indicator caret if you want a chevron. */
}

.zui-dropdown-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: var(--zui-z-dropdown);
  min-width: 220px;
  max-width: 320px;
  padding: var(--zui-space-1) 0;
  margin: 0;
  list-style: none;
  background: var(--zui-surface);
  border: var(--zui-border-hairline);
  border-radius: var(--zui-radius);
  box-shadow: var(--zui-shadow-lg);
  display: none;
}
.zui-dropdown.is-open > .zui-dropdown-menu,
.zui-dropdown:focus-within > .zui-dropdown-menu { display: block; }

/* Align left when right edge of the screen is too close. */
.zui-dropdown-menu.is-left  { left: 0; right: auto; }
.zui-dropdown-menu.is-up    { top: auto; bottom: calc(100% + 4px); }

.zui-dropdown-item {
  display: flex;
  align-items: center;
  gap: var(--zui-space-3);
  width: 100%;
  padding: var(--zui-space-2) var(--zui-space-4);
  font-family: var(--zui-font-family);
  font-size: var(--zui-text-sm);
  font-weight: var(--zui-font-medium);
  line-height: 1.4;
  color: var(--zui-text-body);
  text-align: left;
  text-decoration: none;
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: background var(--zui-transition-fast);
}
.zui-dropdown-item:hover { background: rgb(var(--gray-100)); }
.zui-dropdown-item:focus-visible { background: rgb(var(--gray-100)); outline: none; }
.zui-dropdown-item > .material-icons,
.zui-dropdown-item > .ti,
.zui-dropdown-item > i {
  font-size: 18px;
  color: var(--zui-text-soft);
  flex-shrink: 0;
}
.zui-dropdown-item.is-danger { color: rgb(var(--danger)); }
.zui-dropdown-item.is-danger:hover { background: rgba(var(--danger), 0.08); }
.zui-dropdown-item.is-danger > i { color: rgb(var(--danger)); }
.zui-dropdown-item:disabled,
.zui-dropdown-item.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

.zui-dropdown-divider {
  height: 1px;
  margin: var(--zui-space-1) 0;
  background: rgb(var(--gray-100));
  border: 0;
}
.zui-dropdown-header {
  padding: var(--zui-space-2) var(--zui-space-4);
  font-size: var(--zui-text-xs);
  font-weight: var(--zui-font-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--zui-text-soft);
}


/* ════════════════════════════════════════════════════════════════
 *  3. FORM FIELD (canonical input/select/textarea wrapper)
 *  Mirrors the .form-field-* in PWA buttons.css — same names, both
 *  surfaces use identical markup.
 * ════════════════════════════════════════════════════════════════ */

.form-field {
  margin: 0 0 var(--zui-space-4);
}
.form-field-label {
  display: block;
  font-size: var(--zui-input-label-fs);
  font-weight: var(--zui-font-medium);
  color: var(--zui-text-muted);
  margin-bottom: var(--zui-space-2);
  line-height: 1.3;
}
.form-field-label .is-required::after {
  content: " *";
  color: rgb(var(--danger));
}
.form-field-control {
  display: block;
  width: 100%;
  height: var(--zui-input-h);
  padding: var(--zui-input-py) var(--zui-input-px);
  font-family: var(--zui-font-family);
  font-size: var(--zui-input-fs);
  color: var(--zui-text-strong);
  background: var(--zui-surface);
  border: 1px solid rgb(var(--gray-300));
  border-radius: var(--zui-input-radius);
  box-sizing: border-box;
  transition: border-color var(--zui-transition), box-shadow var(--zui-transition);
}
select.form-field-control {
  -webkit-appearance: menulist;
  appearance: menulist;
  padding-right: 32px;
}
textarea.form-field-control {
  height: auto;
  min-height: 88px;
  resize: vertical;
}
.form-field-control:focus {
  outline: none;
  border-color: rgb(var(--primary));
  box-shadow: var(--zui-focus-ring);
}
.form-field-control:disabled,
.form-field-control[readonly] {
  background: var(--zui-surface-sunken);
  color: var(--zui-text-muted);
  cursor: not-allowed;
}
.form-field-control.is-invalid {
  border-color: rgb(var(--danger));
  box-shadow: 0 0 0 3px rgba(var(--danger), 0.15);
}
.form-field-hint {
  display: block;
  font-size: var(--zui-input-hint-fs);
  color: var(--zui-text-soft);
  margin-top: var(--zui-space-1);
  line-height: 1.4;
}
.form-field-error {
  display: block;
  font-size: var(--zui-input-hint-fs);
  color: rgb(var(--danger));
  margin-top: var(--zui-space-1);
  font-weight: var(--zui-font-medium);
}

/* Inline icon adornments (prepend/append). */
.form-field-control-group {
  position: relative;
  display: flex;
  align-items: stretch;
}
.form-field-control-group .form-field-control { flex: 1; }
.form-field-control-group .form-field-icon-left,
.form-field-control-group .form-field-icon-right {
  position: absolute; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center;
  color: var(--zui-text-soft); pointer-events: none;
}
.form-field-control-group .form-field-icon-left  { left: 12px; }
.form-field-control-group .form-field-icon-right { right: 12px; }
.form-field-control-group:has(.form-field-icon-left)  .form-field-control { padding-left: 38px; }
.form-field-control-group:has(.form-field-icon-right) .form-field-control { padding-right: 38px; }

/* 2-column grid for short fields side-by-side. */
.form-field-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--zui-space-4);
}
.form-field-grid-2 > .form-field { margin: 0; }
@media (max-width: 540px) {
  .form-field-grid-2 { grid-template-columns: 1fr; }
}

/* Inline toggle row. */
.form-field-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--zui-space-3);
  background: var(--zui-surface);
  border: var(--zui-border-hairline);
  border-radius: var(--zui-input-radius);
  margin: 0 0 var(--zui-space-4);
}
.form-field-toggle .form-field-label { margin: 0; }


/* ════════════════════════════════════════════════════════════════
 *  4. TABLE (canonical data table)
 *  Use as: <table class="zui-table"><thead>…<tbody>…</table>
 * ════════════════════════════════════════════════════════════════ */

.zui-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-family: var(--zui-font-family);
  font-size: var(--zui-text-sm);
  color: var(--zui-text-body);
  background: var(--zui-surface);
}
.zui-table thead th {
  padding: var(--zui-space-3) var(--zui-space-4);
  text-align: left;
  font-size: var(--zui-text-xs);
  font-weight: var(--zui-font-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--zui-text-soft);
  background: var(--zui-surface-muted);
  border-bottom: var(--zui-border-hairline);
  position: sticky;
  top: 0;
  z-index: var(--zui-z-sticky);
  white-space: nowrap;
}
.zui-table thead th.is-sortable {
  cursor: pointer;
  user-select: none;
}
.zui-table thead th.is-sortable::after {
  content: "↕";
  margin-left: var(--zui-space-1);
  opacity: 0.4;
  font-size: 12px;
}
.zui-table thead th.is-sorted-asc::after  { content: "↑"; opacity: 1; color: rgb(var(--primary)); }
.zui-table thead th.is-sorted-desc::after { content: "↓"; opacity: 1; color: rgb(var(--primary)); }

.zui-table tbody td {
  padding: var(--zui-space-3) var(--zui-space-4);
  height: 48px;
  border-bottom: var(--zui-border-hairline);
  vertical-align: middle;
}
.zui-table tbody tr:hover td { background: var(--zui-surface-muted); }
.zui-table tbody tr.is-selected td { background: rgba(var(--primary), 0.05); }
.zui-table tbody tr:last-child td { border-bottom: 0; }

/* Compact + comfortable density variants. */
.zui-table.is-compact tbody td    { padding: var(--zui-space-2) var(--zui-space-3); height: 40px; }
.zui-table.is-comfortable tbody td { padding: var(--zui-space-4) var(--zui-space-4); height: 56px; }

/* Striped rows. */
.zui-table.is-striped tbody tr:nth-child(odd) td { background: var(--zui-surface-muted); }
.zui-table.is-striped tbody tr:nth-child(odd):hover td { background: rgb(var(--gray-100)); }

/* Cell alignment helpers. */
.zui-table .is-right    { text-align: right; }
.zui-table .is-center   { text-align: center; }
.zui-table .is-nowrap   { white-space: nowrap; }
.zui-table .is-shrink   { width: 1%; white-space: nowrap; }   /* shrink to content (e.g. actions cell) */

/* Empty state row. */
.zui-table tbody tr.is-empty td {
  padding: var(--zui-space-12) var(--zui-space-4);
  text-align: center;
  color: var(--zui-text-soft);
}

/* Wrapper for scrolling on small screens. */
.zui-table-wrap {
  width: 100%;
  overflow-x: auto;
  border-radius: var(--zui-radius);
  border: var(--zui-border-hairline);
}


/* ════════════════════════════════════════════════════════════════
 *  5. ALERT (inline notice — Bootstrap-compat names)
 *  Use: <div class="zui-alert zui-alert-success">…</div>
 *  Dismissible: add .is-dismissible + a close button.
 * ════════════════════════════════════════════════════════════════ */

.zui-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--zui-space-3);
  padding: var(--zui-space-3) var(--zui-space-4);
  font-size: var(--zui-text-sm);
  border-radius: var(--zui-radius);
  border: 1px solid transparent;
  margin: 0 0 var(--zui-space-4);
}
.zui-alert > .material-icons,
.zui-alert > .ti,
.zui-alert > i {
  font-size: 20px;
  flex-shrink: 0;
  line-height: 1.2;
}
.zui-alert-body { flex: 1; }
.zui-alert-title {
  font-weight: var(--zui-font-semibold);
  margin: 0 0 var(--zui-space-1);
}
.zui-alert-close {
  background: none;
  border: 0;
  padding: 0 var(--zui-space-1);
  cursor: pointer;
  color: inherit;
  opacity: 0.7;
  flex-shrink: 0;
}
.zui-alert-close:hover { opacity: 1; }

/* Soft variants (default) — light tinted background. */
.zui-alert-success { background: rgba(var(--success), 0.08); color: rgb(var(--success)); border-color: rgba(var(--success), 0.20); }
.zui-alert-danger  { background: rgba(var(--danger), 0.08);  color: rgb(var(--danger));  border-color: rgba(var(--danger), 0.20);  }
.zui-alert-warning { background: rgba(var(--warning), 0.10); color: rgb(var(--warning)); border-color: rgba(var(--warning), 0.22); }
.zui-alert-info    { background: rgba(var(--info), 0.08);    color: rgb(var(--info));    border-color: rgba(var(--info), 0.20);    }
.zui-alert-neutral { background: rgb(var(--gray-50));        color: rgb(var(--gray-800)); border-color: rgb(var(--gray-200));      }


/* ════════════════════════════════════════════════════════════════
 *  6. TOAST (floating notification)
 *  Use a fixed container at .zui-toast-container; F7's toast can be
 *  styled via .toast-success / .toast-error / etc. mapped here.
 * ════════════════════════════════════════════════════════════════ */

.zui-toast-container {
  position: fixed;
  top: var(--zui-space-4);
  right: var(--zui-space-4);
  z-index: var(--zui-z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--zui-space-2);
  pointer-events: none;
  max-width: calc(100vw - var(--zui-space-8));
}
.zui-toast-container > * { pointer-events: auto; }

.zui-toast {
  min-width: 280px;
  max-width: 420px;
  padding: var(--zui-space-3) var(--zui-space-4);
  background: var(--zui-text-strong);
  color: #fff;
  font-size: var(--zui-text-sm);
  border-radius: var(--zui-radius);
  box-shadow: var(--zui-shadow-lg);
  display: flex;
  align-items: center;
  gap: var(--zui-space-2);
  animation: zui-toast-in var(--zui-transition) both;
}
@keyframes zui-toast-in {
  from { opacity: 0; transform: translateX(20px); }
  to   { opacity: 1; transform: translateX(0); }
}
.zui-toast-success { background: rgb(var(--success)); }
.zui-toast-danger  { background: rgb(var(--danger));  }
.zui-toast-warning { background: rgb(var(--warning)); }
.zui-toast-info    { background: rgb(var(--info));    }

/* Map Framework7's existing toast cssClass → zui look. */
.toast-success { background: rgb(var(--success)) !important; }
.toast-error,
.toast-danger  { background: rgb(var(--danger))  !important; }
.toast-warning { background: rgb(var(--warning)) !important; }
.toast-info    { background: rgb(var(--info))    !important; }


/* ════════════════════════════════════════════════════════════════
 *  P1 COMPONENTS — landed 2026-06-05
 *  card, badge, avatar, tabs, spinner, progress, tooltip, switch
 *  + skeleton loader. All using tokens from zui-tokens.css.
 * ════════════════════════════════════════════════════════════════ */


/* ── 7. CARD ─────────────────────────────────────────────────────
 * .zui-card                  base surface
 * .zui-card-header           top bar (title + actions)
 * .zui-card-body             main content (default padding)
 * .zui-card-footer           bottom bar (alignment helpers)
 * .zui-card-image            cover image (top, edge-to-edge)
 * .zui-card-title            h-class inside card-header
 * .zui-card-actions          action group inside card-header
 * Modifiers: .is-hoverable / .is-flat / .is-clickable
 * Stat-card sub-pattern at the bottom.
 */
.zui-card {
  background: var(--zui-surface);
  border: var(--zui-border-hairline);
  border-radius: var(--zui-radius);
  overflow: hidden;
  transition: box-shadow var(--zui-transition), transform var(--zui-transition);
}
.zui-card.is-flat       { border: 0; box-shadow: none; background: var(--zui-surface-muted); }
.zui-card.is-hoverable:hover  { box-shadow: var(--zui-shadow-md); transform: translateY(-2px); }
.zui-card.is-clickable  { cursor: pointer; }
.zui-card.is-clickable:hover { box-shadow: var(--zui-shadow); }

.zui-card-header {
  display: flex;
  align-items: center;
  gap: var(--zui-space-3);
  padding: var(--zui-space-4) var(--zui-space-5);
  border-bottom: var(--zui-border-hairline);
}
.zui-card-title {
  margin: 0;
  font-size: var(--zui-text-lg);
  font-weight: var(--zui-font-semibold);
  color: var(--zui-text-strong);
  flex: 1;
  line-height: 1.3;
}
.zui-card-subtitle {
  display: block;
  font-size: var(--zui-text-xs);
  font-weight: var(--zui-font-medium);
  color: var(--zui-text-soft);
  margin-top: 2px;
}
.zui-card-actions {
  display: flex;
  align-items: center;
  gap: var(--zui-space-2);
}
.zui-card-body {
  padding: var(--zui-space-5);
}
.zui-card-body.is-compact { padding: var(--zui-space-3) var(--zui-space-4); }
.zui-card-footer {
  display: flex;
  align-items: center;
  gap: var(--zui-space-3);
  padding: var(--zui-space-3) var(--zui-space-5);
  border-top: var(--zui-border-hairline);
  background: var(--zui-surface-muted);
}
.zui-card-footer.is-end { justify-content: flex-end; }
.zui-card-image {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--zui-radius) var(--zui-radius) 0 0;
}

/* Stat-card — KPI tile for dashboards. */
.zui-stat-card {
  padding: var(--zui-space-5);
  background: var(--zui-surface);
  border: var(--zui-border-hairline);
  border-radius: var(--zui-radius);
}
.zui-stat-card-label {
  font-size: var(--zui-text-xs);
  font-weight: var(--zui-font-medium);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--zui-text-soft);
  margin-bottom: var(--zui-space-2);
}
.zui-stat-card-value {
  font-size: var(--zui-text-3xl);
  font-weight: var(--zui-font-bold);
  color: var(--zui-text-strong);
  line-height: 1.1;
}
.zui-stat-card-change {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: var(--zui-space-2);
  font-size: var(--zui-text-xs);
  font-weight: var(--zui-font-semibold);
}
.zui-stat-card-change.is-up   { color: rgb(var(--success)); }
.zui-stat-card-change.is-down { color: rgb(var(--danger));  }


/* ── 8. BADGE ────────────────────────────────────────────────────
 * Pill/chip styled to match Axelit's _badges.scss.
 * .zui-badge .zui-badge-{colour}        solid (default)
 * .zui-badge-soft-{colour}              tinted background
 * .zui-badge-outline-{colour}           hollow
 * .zui-badge-sm / .zui-badge-lg         size modifiers
 * .zui-badge-pill                       fully rounded
 * .zui-badge-dot                        single dot indicator
 */
.zui-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  font-size: var(--zui-text-xs);
  font-weight: var(--zui-font-semibold);
  line-height: 1.4;
  border-radius: var(--zui-radius-sm);
  border: 1px solid transparent;
  white-space: nowrap;
  background: rgb(var(--gray-100));
  color: rgb(var(--gray-700));
}
.zui-badge-sm { padding: 1px 6px; font-size: 10px; }
.zui-badge-lg { padding: 4px 12px; font-size: var(--zui-text-sm); }
.zui-badge-pill { border-radius: var(--zui-radius-pill); }

/* Solid */
.zui-badge-primary   { background: rgb(var(--primary));   color: #fff; }
.zui-badge-secondary { background: rgb(var(--secondary)); color: #1e293b; }
.zui-badge-success   { background: rgb(var(--success));   color: #fff; }
.zui-badge-danger    { background: rgb(var(--danger));    color: #fff; }
.zui-badge-warning   { background: rgb(var(--warning));   color: #fff; }
.zui-badge-info      { background: rgb(var(--info));      color: #fff; }

/* Soft */
.zui-badge-soft-primary   { background: rgba(var(--primary), 0.12);   color: rgb(var(--primary));   }
.zui-badge-soft-secondary { background: rgba(var(--secondary), 0.20); color: rgb(var(--gray-800));  }
.zui-badge-soft-success   { background: rgba(var(--success), 0.14);   color: rgb(var(--success));   }
.zui-badge-soft-danger    { background: rgba(var(--danger), 0.10);    color: rgb(var(--danger));    }
.zui-badge-soft-warning   { background: rgba(var(--warning), 0.14);   color: rgb(var(--warning));   }
.zui-badge-soft-info      { background: rgba(var(--info), 0.14);      color: rgb(var(--info));      }

/* Outline */
.zui-badge-outline-primary   { background: transparent; color: rgb(var(--primary));   border-color: rgb(var(--primary));   }
.zui-badge-outline-secondary { background: transparent; color: rgb(var(--gray-800));  border-color: rgb(var(--gray-400));  }
.zui-badge-outline-success   { background: transparent; color: rgb(var(--success));   border-color: rgb(var(--success));   }
.zui-badge-outline-danger    { background: transparent; color: rgb(var(--danger));    border-color: rgb(var(--danger));    }
.zui-badge-outline-warning   { background: transparent; color: rgb(var(--warning));   border-color: rgb(var(--warning));   }
.zui-badge-outline-info      { background: transparent; color: rgb(var(--info));      border-color: rgb(var(--info));      }

/* Dot indicator — pure circle, no text. */
.zui-badge-dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border-radius: 50%;
}


/* ── 9. AVATAR ───────────────────────────────────────────────────
 * .zui-avatar-{xs,sm,md,lg,xl}   24 / 32 / 40 / 56 / 80 px
 * .zui-avatar-square             rounded corners instead of circle
 * .zui-avatar-initials           text-based fallback w/ colour
 * .zui-avatar-status             .is-online / .is-offline indicator
 * .zui-avatar-group              overlapping cluster
 */
.zui-avatar {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgb(var(--gray-200));
  color: rgb(var(--gray-700));
  font-size: var(--zui-text-sm);
  font-weight: var(--zui-font-semibold);
  overflow: hidden;
  flex-shrink: 0;
}
.zui-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.zui-avatar-xs { width: 24px; height: 24px; font-size: 10px; }
.zui-avatar-sm { width: 32px; height: 32px; font-size: 12px; }
.zui-avatar-md { width: 40px; height: 40px; }
.zui-avatar-lg { width: 56px; height: 56px; font-size: var(--zui-text-lg); }
.zui-avatar-xl { width: 80px; height: 80px; font-size: var(--zui-text-2xl); }
.zui-avatar-square { border-radius: var(--zui-radius); }

/* Status dot — small circle bottom-right. */
.zui-avatar-status::after {
  content: "";
  position: absolute;
  bottom: 0;
  right: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgb(var(--gray-400));
  border: 2px solid var(--zui-surface);
}
.zui-avatar-status.is-online::after  { background: rgb(var(--success)); }
.zui-avatar-status.is-busy::after    { background: rgb(var(--danger));  }
.zui-avatar-status.is-away::after    { background: rgb(var(--warning)); }

/* Avatar group — overlapping cluster. */
.zui-avatar-group {
  display: inline-flex;
}
.zui-avatar-group .zui-avatar {
  border: 2px solid var(--zui-surface);
  margin-left: -8px;
}
.zui-avatar-group .zui-avatar:first-child { margin-left: 0; }


/* ── 10. TABS ────────────────────────────────────────────────────
 * Three styles: .zui-tabs (default line) / .is-pill / .is-box
 *   <ul class="zui-tabs">
 *     <li><a class="zui-tab is-active">Tab 1</a></li>
 *     <li><a class="zui-tab">Tab 2</a></li>
 *   </ul>
 */
.zui-tabs {
  display: flex;
  align-items: center;
  gap: 0;
  list-style: none;
  padding: 0;
  margin: 0 0 var(--zui-space-5);
  border-bottom: var(--zui-border-hairline);
}
.zui-tab {
  display: inline-flex;
  align-items: center;
  gap: var(--zui-space-2);
  padding: var(--zui-space-3) var(--zui-space-4);
  font-size: var(--zui-text-sm);
  font-weight: var(--zui-font-medium);
  color: var(--zui-text-soft);
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  cursor: pointer;
  text-decoration: none;
  transition: color var(--zui-transition), border-color var(--zui-transition);
}
.zui-tab:hover { color: var(--zui-text-body); }
.zui-tab.is-active {
  color: rgb(var(--primary));
  border-bottom-color: rgb(var(--primary));
}
.zui-tab > .zui-badge { margin-left: var(--zui-space-1); }

/* Pill variant — rounded filled. */
.zui-tabs.is-pill {
  border-bottom: 0;
  gap: var(--zui-space-2);
  background: var(--zui-surface-muted);
  padding: 4px;
  border-radius: var(--zui-radius-pill);
  display: inline-flex;
  width: auto;
}
.zui-tabs.is-pill .zui-tab {
  border: 0;
  margin: 0;
  border-radius: var(--zui-radius-pill);
  padding: 6px var(--zui-space-3);
}
.zui-tabs.is-pill .zui-tab.is-active {
  background: var(--zui-surface);
  color: rgb(var(--primary));
  box-shadow: var(--zui-shadow-sm);
}

/* Box variant — segmented control. */
.zui-tabs.is-box {
  border-bottom: 0;
  gap: -1px;
  border: var(--zui-border-hairline);
  border-radius: var(--zui-radius);
  background: var(--zui-surface);
  display: inline-flex;
  overflow: hidden;
}
.zui-tabs.is-box .zui-tab {
  border: 0;
  border-right: var(--zui-border-hairline);
  margin: 0;
  border-radius: 0;
  padding: var(--zui-space-2) var(--zui-space-4);
}
.zui-tabs.is-box .zui-tab:last-child { border-right: 0; }
.zui-tabs.is-box .zui-tab.is-active {
  background: rgb(var(--primary));
  color: #fff;
}


/* ── 11. SPINNER + SKELETON LOADER ───────────────────────────────
 * .zui-spinner-{sm,md,lg}        circular loader (16/24/32 px)
 * .zui-skeleton                  shimmer line
 * .zui-skeleton-circle           shimmer circle (for avatar slots)
 * .zui-skeleton-box              shimmer rectangle (for cards)
 */
.zui-spinner {
  display: inline-block;
  width: 24px;
  height: 24px;
  border: 3px solid rgba(var(--primary), 0.18);
  border-top-color: rgb(var(--primary));
  border-radius: 50%;
  animation: zui-spin 0.8s linear infinite;
  vertical-align: middle;
}
.zui-spinner-sm { width: 16px; height: 16px; border-width: 2px; }
.zui-spinner-lg { width: 32px; height: 32px; border-width: 4px; }

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

.zui-skeleton {
  display: inline-block;
  height: 12px;
  width: 100%;
  background: linear-gradient(
    90deg,
    rgb(var(--gray-200)) 0%,
    rgb(var(--gray-100)) 50%,
    rgb(var(--gray-200)) 100%
  );
  background-size: 200% 100%;
  border-radius: var(--zui-radius-sm);
  animation: zui-shimmer 1.4s linear infinite;
}
.zui-skeleton-box    { display: block; height: 100px; }
.zui-skeleton-circle { width: 40px; height: 40px; border-radius: 50%; }

@keyframes zui-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}


/* ── 12. PROGRESS ────────────────────────────────────────────────
 * .zui-progress                  outer bar
 *   .zui-progress-bar              filled inner bar (set width:)
 * Modifiers: .is-{primary,success,danger,warning,info}
 *            .is-sm / .is-lg
 *            .is-striped / .is-indeterminate
 */
.zui-progress {
  position: relative;
  width: 100%;
  height: 8px;
  background: rgb(var(--gray-200));
  border-radius: var(--zui-radius-pill);
  overflow: hidden;
}
.zui-progress.is-sm { height: 4px; }
.zui-progress.is-lg { height: 12px; }

.zui-progress-bar {
  height: 100%;
  background: rgb(var(--primary));
  border-radius: inherit;
  transition: width var(--zui-transition);
}
.zui-progress.is-success .zui-progress-bar { background: rgb(var(--success)); }
.zui-progress.is-danger  .zui-progress-bar { background: rgb(var(--danger));  }
.zui-progress.is-warning .zui-progress-bar { background: rgb(var(--warning)); }
.zui-progress.is-info    .zui-progress-bar { background: rgb(var(--info));    }

.zui-progress.is-striped .zui-progress-bar {
  background-image: linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.18) 25%,
    transparent 25%,
    transparent 50%,
    rgba(255, 255, 255, 0.18) 50%,
    rgba(255, 255, 255, 0.18) 75%,
    transparent 75%,
    transparent
  );
  background-size: 16px 16px;
}
.zui-progress.is-indeterminate .zui-progress-bar {
  width: 40% !important;
  animation: zui-progress-indeterminate 1.4s ease-in-out infinite;
}
@keyframes zui-progress-indeterminate {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(300%); }
}


/* ── 13. TOOLTIP ─────────────────────────────────────────────────
 * Pure CSS tooltip via data-tooltip + .zui-tooltip-{top,bottom,left,right}.
 * Default direction: top.
 *   <button class="zui-tooltip" data-tooltip="Save changes">…</button>
 */
.zui-tooltip { position: relative; }
.zui-tooltip::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%) translateY(2px);
  padding: 4px 8px;
  font-size: var(--zui-text-xs);
  font-weight: var(--zui-font-medium);
  color: #fff;
  background: rgb(var(--gray-900));
  border-radius: var(--zui-radius-sm);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--zui-transition-fast), transform var(--zui-transition-fast);
  z-index: var(--zui-z-popover);
}
.zui-tooltip:hover::after,
.zui-tooltip:focus-visible::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.zui-tooltip-bottom::after { bottom: auto; top: calc(100% + 6px); transform: translateX(-50%) translateY(-2px); }
.zui-tooltip-bottom:hover::after { transform: translateX(-50%) translateY(0); }
.zui-tooltip-left::after { bottom: 50%; left: auto; right: calc(100% + 6px); transform: translate(2px, 50%); }
.zui-tooltip-left:hover::after { transform: translate(0, 50%); }
.zui-tooltip-right::after { bottom: 50%; left: calc(100% + 6px); transform: translate(-2px, 50%); }
.zui-tooltip-right:hover::after { transform: translate(0, 50%); }


/* ── 14. SWITCH (branded toggle) ─────────────────────────────────
 * <label class="zui-switch">
 *   <input type="checkbox">
 *   <span class="zui-switch-track"><span class="zui-switch-thumb"></span></span>
 *   <span class="zui-switch-label">Show in timeline</span>
 * </label>
 */
.zui-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--zui-space-2);
  cursor: pointer;
  user-select: none;
}
.zui-switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.zui-switch-track {
  position: relative;
  width: 44px;
  height: 24px;
  background: rgb(var(--gray-300));
  border-radius: var(--zui-radius-pill);
  transition: background var(--zui-transition);
}
.zui-switch-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  background: #fff;
  border-radius: 50%;
  box-shadow: var(--zui-shadow-sm);
  transition: transform var(--zui-transition);
}
.zui-switch input:checked + .zui-switch-track {
  background: rgb(var(--primary));
}
.zui-switch input:checked + .zui-switch-track .zui-switch-thumb {
  transform: translateX(20px);
}
.zui-switch input:focus-visible + .zui-switch-track {
  box-shadow: var(--zui-focus-ring);
}
.zui-switch input:disabled + .zui-switch-track {
  opacity: 0.5;
  cursor: not-allowed;
}
.zui-switch-label {
  font-size: var(--zui-text-sm);
  color: var(--zui-text-body);
  font-weight: var(--zui-font-medium);
}

/* Compact sm + comfortable lg variants. */
.zui-switch-sm .zui-switch-track { width: 36px; height: 20px; }
.zui-switch-sm .zui-switch-thumb { width: 16px; height: 16px; }
.zui-switch-sm input:checked + .zui-switch-track .zui-switch-thumb { transform: translateX(16px); }
.zui-switch-lg .zui-switch-track { width: 52px; height: 28px; }
.zui-switch-lg .zui-switch-thumb { width: 24px; height: 24px; }
.zui-switch-lg input:checked + .zui-switch-track .zui-switch-thumb { transform: translateX(24px); }
