/* ==========================================================================
   MX UI · Components  v2
   Scoped under .mx so component styles never leak into unrelated markup.
   Depends on tokens.css.

   INDEX
   01 Base            02 Button           03 Badge
   04 Card            05 Field/Input      06 Select/Textarea
   07 Checkbox/Radio  08 Switch           09 Slider
   10 Segmented       11 Tabs             12 Accordion
   13 Table           14 Avatar           15 Stat
   16 Alert           17 Toast            18 Progress
   19 Skeleton        20 Spinner          21 Tooltip
   22 Kbd             23 Separator        24 Empty state
   25 Dialog          26 Drawer           27 Dropdown
   28 Breadcrumb      29 Pagination       30 Utilities
   ========================================================================== */

/* ------------------------------------------------------------ 01 · Base */
.mx,
.mx *,
.mx *::before,
.mx *::after {
  box-sizing: border-box;
}

.mx {
  font-family: var(--mx-font);
  font-size: var(--mx-text-base);
  font-optical-sizing: auto;
  line-height: 1.5;
  color: var(--mx-ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.mx [x-cloak] {
  display: none !important;
}

/* ---------------------------------------------------------- 02 · Button
   One height scale for everything: sm 32 · md 36 · lg 40.
   Weight 500, tight padding, no bouncy hover — color + press only.     */
.mx-btn {
  --_h: var(--mx-h-md);
  --_px: 14px;
  --_fs: var(--mx-text-sm);
  --_bg: var(--mx-brand);
  --_fg: var(--mx-on-brand);
  --_bd: transparent;
  --_sh: none;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: var(--_h);
  padding: 0 var(--_px);
  font: inherit;
  font-size: var(--_fs);
  font-weight: 500;
  letter-spacing: -0.006em;
  line-height: 1;
  white-space: nowrap;
  border-radius: var(--mx-radius);
  border: 1px solid var(--_bd);
  background: var(--_bg);
  color: var(--_fg);
  box-shadow: var(--_sh);
  cursor: pointer;
  user-select: none;
  text-decoration: none;
  transition: background var(--mx-dur) var(--mx-ease-out),
    border-color var(--mx-dur), color var(--mx-dur),
    box-shadow var(--mx-dur), transform var(--mx-dur-fast);
}
.mx-btn:active {
  transform: scale(0.98);
}
.mx-btn:focus-visible {
  outline: none;
  box-shadow: var(--mx-ring);
}
.mx-btn[disabled],
.mx-btn[aria-disabled="true"] {
  opacity: 0.5;
  pointer-events: none;
}
.mx-btn svg {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
}

/* variants */
.mx-btn--primary {
  --_bg: var(--mx-brand);
  --_fg: var(--mx-on-brand);
  --_sh: inset 0 1px 0 rgba(255, 255, 255, 0.14), var(--mx-shadow-xs);
}
.mx-btn--primary:hover {
  --_bg: var(--mx-brand-deep);
}
.mx-btn--secondary {
  --_bg: var(--mx-surface-strong);
  --_fg: var(--mx-ink);
}
.mx-btn--secondary:hover {
  --_bg: var(--mx-bg-2);
}
.mx-btn--outline {
  --_bg: var(--mx-surface);
  --_fg: var(--mx-ink);
  --_bd: var(--mx-line-strong);
  --_sh: var(--mx-shadow-xs);
}
.mx-btn--outline:hover {
  --_bg: var(--mx-surface-soft);
}
.mx-btn--ghost {
  --_bg: transparent;
  --_fg: var(--mx-ink-soft);
}
.mx-btn--ghost:hover {
  --_bg: var(--mx-surface-strong);
  --_fg: var(--mx-ink);
}
/* destructive = shadcn's naming; danger kept as an alias */
.mx-btn--danger,
.mx-btn--destructive {
  --_bg: var(--mx-red);
  --_fg: #fff;
  --_sh: inset 0 1px 0 rgba(255, 255, 255, 0.14), var(--mx-shadow-xs);
}
.mx-btn--danger:hover,
.mx-btn--destructive:hover {
  --_bg: #dc2626;
}
/* soft destructive — quiet secondary destructive action (e.g. Reject) */
.mx-btn--destructive-soft {
  --_bg: var(--mx-red-tint);
  --_fg: var(--mx-red-fg);
}
.mx-btn--destructive-soft:hover {
  --_bg: var(--mx-red);
  --_fg: #fff;
}
.mx-btn--link {
  --_bg: transparent;
  --_fg: var(--mx-brand-fg);
  --_px: 2px;
  height: auto;
}
.mx-btn--link:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* sizes */
.mx-btn--sm {
  --_h: var(--mx-h-sm);
  --_px: 11px;
  --_fs: var(--mx-text-xs);
  border-radius: var(--mx-radius-sm);
  gap: 6px;
}
.mx-btn--sm svg {
  width: 13px;
  height: 13px;
}
.mx-btn--lg {
  --_h: var(--mx-h-lg);
  --_px: 18px;
  --_fs: var(--mx-text-base);
}
.mx-btn--icon {
  width: var(--_h);
  padding: 0;
}
.mx-btn--block {
  width: 100%;
}

/* loading */
.mx-btn.is-loading {
  pointer-events: none;
  opacity: 0.72;
}
.mx-btn.is-loading::before {
  content: "";
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  border-top-color: transparent;
  animation: mx-spin 0.7s linear infinite;
}
@keyframes mx-spin {
  to {
    transform: rotate(360deg);
  }
}

/* button group */
.mx-btn-group {
  display: inline-flex;
}
.mx-btn-group .mx-btn {
  border-radius: 0;
}
.mx-btn-group .mx-btn:first-child {
  border-radius: var(--mx-radius) 0 0 var(--mx-radius);
}
.mx-btn-group .mx-btn:last-child {
  border-radius: 0 var(--mx-radius) var(--mx-radius) 0;
}
.mx-btn-group .mx-btn--outline + .mx-btn--outline {
  margin-left: -1px;
}

/* ----------------------------------------------------------- 03 · Badge */
.mx-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 22px;
  padding: 0 8px;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  line-height: 1;
  border-radius: var(--mx-radius-pill);
  background: var(--mx-surface-strong);
  color: var(--mx-ink-soft);
  white-space: nowrap;
}
.mx-badge--brand    { background: var(--mx-brand-tint); color: var(--mx-brand-fg); }
.mx-badge--success  { background: var(--mx-green-tint); color: var(--mx-green-fg); }
.mx-badge--warning  { background: var(--mx-amber-tint); color: var(--mx-amber-fg); }
.mx-badge--danger   { background: var(--mx-red-tint);   color: var(--mx-red-fg); }
.mx-badge--info     { background: var(--mx-cyan-tint);  color: var(--mx-cyan-fg); }
.mx-badge--outline  { background: transparent; box-shadow: inset 0 0 0 1px var(--mx-line-strong); }
.mx-badge__dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
}

/* ------------------------------------------------- Active-filter chips */
.mx-filter-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.mx-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  padding: 0 6px 0 10px;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  color: var(--mx-brand-fg);
  background: var(--mx-brand-tint);
  border-radius: var(--mx-radius-pill);
  white-space: nowrap;
  max-width: 260px;
}
.mx-chip > span {
  overflow: hidden;
  text-overflow: ellipsis;
}
.mx-chip__x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity var(--mx-dur-fast), background var(--mx-dur-fast);
}
.mx-chip__x:hover {
  opacity: 1;
  background: color-mix(in srgb, var(--mx-brand) 18%, transparent);
}
.mx-chip__x svg { width: 11px; height: 11px; }
.mx-chip__clear {
  font: inherit;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  color: var(--mx-muted);
  background: none;
  border: none;
  padding: 0 6px;
  cursor: pointer;
  transition: color var(--mx-dur-fast);
}
.mx-chip__clear:hover { color: var(--mx-ink); }

/* ------------------------------------------------------------ 04 · Card */
.mx-card {
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  box-shadow: var(--mx-shadow-xs);
}
.mx-card__header {
  padding: 18px 20px 0;
}
.mx-card__title {
  margin: 0;
  font-size: var(--mx-text-md);
  font-weight: 600;
  letter-spacing: -0.011em;
}
.mx-card__desc {
  margin: 3px 0 0;
  font-size: var(--mx-text-sm);
  color: var(--mx-muted);
}
.mx-card__body {
  padding: 18px 20px;
}
.mx-card__footer {
  display: flex;
  align-items: center;
  gap: var(--mx-gap-2);
  padding: 12px 20px;
  border-top: 1px solid var(--mx-line);
}

/* ----------------------------------------------------- 05 · Field/Input */
.mx-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.mx-label {
  font-size: var(--mx-text-sm);
  font-weight: 500;
  color: var(--mx-ink);
  letter-spacing: -0.006em;
}
.mx-label__req {
  color: var(--mx-red-fg);
}
.mx-input {
  height: var(--mx-h-md);
  width: 100%;
  padding: 0 11px;
  font: inherit;
  font-size: var(--mx-text-sm);
  color: var(--mx-ink);
  background: var(--mx-surface);
  border: 1px solid var(--mx-line-strong);
  border-radius: var(--mx-radius);
  box-shadow: var(--mx-shadow-xs);
  transition: border-color var(--mx-dur), box-shadow var(--mx-dur);
}
.mx-input::placeholder {
  color: var(--mx-muted-2);
}
.mx-input:hover {
  border-color: var(--mx-muted-2);
}
.mx-input:focus {
  outline: none;
  border-color: var(--mx-brand);
  box-shadow: var(--mx-ring);
}
.mx-input[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
  background: var(--mx-surface-soft);
}
.mx-input[aria-invalid="true"],
.mx-select[aria-invalid="true"],
.mx-textarea[aria-invalid="true"],
.mx-dtp__trigger[aria-invalid="true"],
.mx-combobox__control[aria-invalid="true"] {
  border-color: var(--mx-red);
}
.mx-input[aria-invalid="true"]:focus,
.mx-select[aria-invalid="true"]:focus,
.mx-textarea[aria-invalid="true"]:focus,
.mx-dtp__trigger[aria-invalid="true"]:focus,
.mx-combobox__control[aria-invalid="true"]:focus-within {
  box-shadow: var(--mx-ring-danger);
}
.mx-input--sm { height: var(--mx-h-sm); border-radius: var(--mx-radius-sm); }
.mx-input--lg { height: var(--mx-h-lg); font-size: var(--mx-text-base); }

.mx-hint {
  font-size: var(--mx-text-xs);
  color: var(--mx-muted);
}
.mx-hint--error {
  color: var(--mx-red-fg);
}

/* input with leading icon / addon */
.mx-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
}
.mx-input-wrap > svg,
.mx-input-wrap > .mx-input-icon {
  position: absolute;
  left: 11px;
  width: 15px;
  height: 15px;
  color: var(--mx-muted-2);
  pointer-events: none;
}
.mx-input-wrap > .mx-input {
  padding-left: 33px;
}

/* input with a trailing affix button (password reveal, clear, unit…) */
.mx-input-wrap--affix > .mx-input {
  padding-left: 11px;
  padding-right: 40px;
}
.mx-input-affix {
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  width: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--mx-muted-2);
  cursor: pointer;
  transition: color var(--mx-dur);
}
.mx-input-affix:hover { color: var(--mx-muted); }
.mx-input-affix:focus-visible { outline: none; color: var(--mx-brand); }
.mx-input-affix > svg { width: 18px; height: 18px; }

/* -------------------------------------------------- 06 · Select/Textarea */
.mx-select {
  appearance: none;
  height: var(--mx-h-md);
  width: 100%;
  padding: 0 32px 0 11px;
  font: inherit;
  font-size: var(--mx-text-sm);
  color: var(--mx-ink);
  background-color: var(--mx-surface);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  border: 1px solid var(--mx-line-strong);
  border-radius: var(--mx-radius);
  box-shadow: var(--mx-shadow-xs);
  cursor: pointer;
  transition: border-color var(--mx-dur), box-shadow var(--mx-dur);
}
.mx-select:hover {
  border-color: var(--mx-muted-2);
}
.mx-select:focus {
  outline: none;
  border-color: var(--mx-brand);
  box-shadow: var(--mx-ring);
}

.mx-textarea {
  width: 100%;
  min-height: 84px;
  padding: 9px 11px;
  font: inherit;
  font-size: var(--mx-text-sm);
  line-height: 1.55;
  color: var(--mx-ink);
  background: var(--mx-surface);
  border: 1px solid var(--mx-line-strong);
  border-radius: var(--mx-radius);
  box-shadow: var(--mx-shadow-xs);
  resize: vertical;
  transition: border-color var(--mx-dur), box-shadow var(--mx-dur);
}
.mx-textarea::placeholder {
  color: var(--mx-muted-2);
}
.mx-textarea:hover {
  border-color: var(--mx-muted-2);
}
.mx-textarea:focus {
  outline: none;
  border-color: var(--mx-brand);
  box-shadow: var(--mx-ring);
}

/* ------------------------------------------------- 07 · Checkbox/Radio */
.mx-check,
.mx-radio {
  display: inline-flex;
  align-items: flex-start;
  gap: 9px;
  cursor: pointer;
  font-size: var(--mx-text-sm);
  line-height: 1.45;
}
.mx-check input,
.mx-radio input {
  appearance: none;
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin: 1.5px 0 0;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line-strong);
  box-shadow: var(--mx-shadow-xs);
  cursor: pointer;
  transition: background var(--mx-dur), border-color var(--mx-dur),
    box-shadow var(--mx-dur);
}
.mx-check input {
  border-radius: 5px;
}
.mx-radio input {
  border-radius: 50%;
}
.mx-check input:hover,
.mx-radio input:hover {
  border-color: var(--mx-muted-2);
}
.mx-check input:focus-visible,
.mx-radio input:focus-visible {
  outline: none;
  box-shadow: var(--mx-ring);
}
.mx-check input:checked,
.mx-radio input:checked {
  background: var(--mx-brand);
  border-color: var(--mx-brand);
}
.mx-check input:checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-size: 10px;
  background-position: center;
  background-repeat: no-repeat;
}
.mx-check input:indeterminate {
  background: var(--mx-brand);
  border-color: var(--mx-brand);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E");
  background-size: 10px;
  background-position: center;
  background-repeat: no-repeat;
}
.mx-radio input:checked {
  border-width: 5px;
  background: #fff;
}
.mx-check__text b,
.mx-radio__text b {
  display: block;
  font-weight: 500;
  color: var(--mx-ink);
}
.mx-check__text span,
.mx-radio__text span {
  color: var(--mx-muted);
  font-size: var(--mx-text-xs);
}

/* ---------------------------------------------------------- 08 · Switch */
.mx-switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  font-size: var(--mx-text-sm);
}
.mx-switch input {
  appearance: none;
  position: relative;
  flex: 0 0 auto;
  width: 34px;
  height: 20px;
  border-radius: var(--mx-radius-pill);
  background: var(--mx-line-strong);
  cursor: pointer;
  transition: background var(--mx-dur-slow) var(--mx-ease-out);
}
.mx-switch input::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.28);
  transition: translate var(--mx-dur-slow) var(--mx-ease-spring);
}
.mx-switch input:checked {
  background: var(--mx-brand);
}
.mx-switch input:checked::after {
  translate: 14px 0;
}
.mx-switch input:focus-visible {
  outline: none;
  box-shadow: var(--mx-ring);
}

/* ---------------------------------------------------------- 09 · Slider */
.mx-slider {
  appearance: none;
  width: 100%;
  height: 16px;
  background: transparent;
  cursor: pointer;
}
.mx-slider::-webkit-slider-runnable-track {
  height: 5px;
  border-radius: var(--mx-radius-pill);
  background: linear-gradient(
    to right,
    var(--mx-brand) var(--mx-slider-fill, 50%),
    var(--mx-surface-strong) var(--mx-slider-fill, 50%)
  );
}
.mx-slider::-webkit-slider-thumb {
  appearance: none;
  width: 16px;
  height: 16px;
  margin-top: -5.5px;
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--mx-line-strong);
  box-shadow: var(--mx-shadow-sm);
  transition: transform var(--mx-dur-fast);
}
.mx-slider::-webkit-slider-thumb:active {
  transform: scale(1.15);
}
.mx-slider::-moz-range-track {
  height: 5px;
  border-radius: var(--mx-radius-pill);
  background: var(--mx-surface-strong);
}
.mx-slider::-moz-range-progress {
  height: 5px;
  border-radius: var(--mx-radius-pill);
  background: var(--mx-brand);
}
.mx-slider::-moz-range-thumb {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--mx-line-strong);
  box-shadow: var(--mx-shadow-sm);
}
.mx-slider:focus-visible {
  outline: none;
}
.mx-slider:focus-visible::-webkit-slider-thumb {
  box-shadow: var(--mx-ring);
}

/* ------------------------------------------------------- 10 · Segmented */
.mx-segmented {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  background: var(--mx-surface-strong);
  border-radius: var(--mx-radius);
}
.mx-segmented__item {
  display: inline-flex;
  align-items: center;
  height: calc(var(--mx-h-sm) - 6px);
  padding: 0 12px;
  font: inherit;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  color: var(--mx-muted);
  background: transparent;
  border: none;
  border-radius: var(--mx-radius-sm);
  cursor: pointer;
  transition: color var(--mx-dur), background var(--mx-dur),
    box-shadow var(--mx-dur);
}
.mx-segmented__item:hover {
  color: var(--mx-ink-soft);
}
.mx-segmented__item.is-active {
  color: var(--mx-ink);
  background: var(--mx-surface);
  box-shadow: var(--mx-shadow-xs);
}
/* Radio-backed variant: a hidden native radio drives the active state (form-data
   source of truth for HTMX filters) — pair each input with a label.mx-segmented__item. */
.mx-segmented > input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.mx-segmented > input[type="radio"]:checked + .mx-segmented__item {
  color: var(--mx-ink);
  background: var(--mx-surface);
  box-shadow: var(--mx-shadow-xs);
}
.mx-segmented > input[type="radio"]:focus-visible + .mx-segmented__item {
  box-shadow: var(--mx-ring);
}

/* ------------------------------------------------------------ 11 · Tabs */
.mx-tabs {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--mx-line);
}
.mx-tabs__item {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: var(--mx-h-md);
  padding: 0 12px;
  margin-bottom: -1px;
  font: inherit;
  font-size: var(--mx-text-sm);
  font-weight: 500;
  color: var(--mx-muted);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: color var(--mx-dur);
}
.mx-tabs__item:hover {
  color: var(--mx-ink-soft);
}
.mx-tabs__item.is-active {
  color: var(--mx-ink);
  border-bottom-color: var(--mx-brand);
}
.mx-tabs__count {
  font-size: 11px;
  padding: 1px 6px;
  border-radius: var(--mx-radius-pill);
  background: var(--mx-surface-strong);
  color: var(--mx-muted);
}
.mx-tabs__panel {
  padding-top: var(--mx-gap-4);
}

/* Icons inside triggers */
.mx-tabs__item svg {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
}

/* Disabled trigger */
.mx-tabs__item:disabled,
.mx-tabs__item[aria-disabled="true"] {
  color: var(--mx-muted-2);
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* Pill list — the shadcn default look (muted track + active pill) */
.mx-tabs--pill {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border-bottom: none;
  background: var(--mx-surface-strong);
  border-radius: var(--mx-radius);
}
.mx-tabs--pill .mx-tabs__item {
  height: calc(var(--mx-h-md) - 8px);
  margin-bottom: 0;
  padding: 0 14px;
  border-bottom: none;
  border-radius: var(--mx-radius-sm);
  transition: color var(--mx-dur), background var(--mx-dur),
    box-shadow var(--mx-dur);
}
.mx-tabs--pill .mx-tabs__item.is-active {
  color: var(--mx-ink);
  background: var(--mx-surface);
  box-shadow: var(--mx-shadow-xs);
}

/* Vertical orientation — list beside the panel */
.mx-tabs-x {
  display: flex;
  gap: var(--mx-gap-5);
  align-items: flex-start;
}
.mx-tabs--vertical {
  flex-direction: column;
  gap: 2px;
  border-bottom: none;
  min-width: 168px;
}
.mx-tabs--vertical .mx-tabs__item {
  width: 100%;
  height: var(--mx-h-md);
  margin-bottom: 0;
  padding: 0 12px;
  justify-content: flex-start;
  border-bottom: none;
  border-radius: var(--mx-radius-sm);
  transition: color var(--mx-dur), background var(--mx-dur);
}
.mx-tabs--vertical .mx-tabs__item.is-active {
  color: var(--mx-ink);
  background: var(--mx-surface-strong);
}
.mx-tabs-x .mx-tabs__panel {
  flex: 1;
  padding-top: 0;
}

/* ------------------------------------------------------- 12 · Accordion */
.mx-accordion {
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  background: var(--mx-surface);
  overflow: hidden;
}
.mx-accordion__item + .mx-accordion__item {
  border-top: 1px solid var(--mx-line);
}
.mx-accordion__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--mx-gap-3);
  padding: 14px 18px;
  font-size: var(--mx-text-sm);
  font-weight: 500;
  cursor: pointer;
  list-style: none;
  transition: background var(--mx-dur);
}
.mx-accordion__item summary::-webkit-details-marker {
  display: none;
}
.mx-accordion__item summary:hover {
  background: var(--mx-surface-soft);
}
.mx-accordion__item summary::after {
  content: "";
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  background: currentColor;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")
    center / contain no-repeat;
  color: var(--mx-muted-2);
  transition: rotate var(--mx-dur-slow) var(--mx-ease-out);
}
.mx-accordion__item[open] summary::after {
  rotate: 180deg;
}
.mx-accordion__content {
  padding: 2px 18px 16px;
  font-size: var(--mx-text-sm);
  color: var(--mx-muted);
  animation: mx-acc-in var(--mx-dur-slow) var(--mx-ease-out);
}
@keyframes mx-acc-in {
  from {
    opacity: 0;
    translate: 0 -4px;
  }
}

/* ----------------------------------------------------------- 13 · Table */
.mx-table-wrap {
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  background: var(--mx-surface);
  box-shadow: var(--mx-shadow-xs);
  overflow: auto;
}
.mx-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--mx-text-sm);
}
.mx-table th,
.mx-table td {
  padding: 10px 16px;
  text-align: left;
  border-bottom: 1px solid var(--mx-line);
}
.mx-table thead th {
  height: 38px;
  padding-block: 0;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  color: var(--mx-muted);
  background: var(--mx-surface-soft);
  white-space: nowrap;
}
.mx-table tbody tr {
  transition: background var(--mx-dur-fast);
}
.mx-table tbody tr:hover {
  background: var(--mx-surface-soft);
}
.mx-table tbody tr:last-child td {
  border-bottom: none;
}
.mx-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* caption (below the table, shadcn-style) */
.mx-table caption {
  caption-side: bottom;
  padding: 12px 16px;
  font-size: var(--mx-text-xs);
  color: var(--mx-muted);
  text-align: left;
}
/* footer / total row */
.mx-table tfoot td,
.mx-table tfoot th {
  height: 42px;
  font-weight: 600;
  color: var(--mx-ink);
  background: var(--mx-surface-soft);
  border-top: 1px solid var(--mx-line-strong);
  border-bottom: none;
}
.mx-table tfoot tr:hover { background: var(--mx-surface-soft); }
/* selectable rows */
.mx-table__check { width: 44px; text-align: center; }
.mx-table__check .mx-check { gap: 0; }
.mx-table tbody tr.is-selected,
.mx-table tbody tr.is-selected:hover { background: var(--mx-brand-tint); }

/* ---------------------------------------------------------- 14 · Avatar */
.mx-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
  border-radius: 50%;
  overflow: hidden;
  background: var(--mx-brand-tint);
  color: var(--mx-brand-fg);
  font-size: var(--mx-text-xs);
  font-weight: 600;
  letter-spacing: 0.01em;
}
.mx-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.mx-avatar--sm { width: 24px; height: 24px; font-size: 10px; }
.mx-avatar--lg { width: 44px; height: 44px; font-size: var(--mx-text-base); }

/* Status dot — presence/state pinned to the avatar's corner. The dot needs
   overflow visible, so the image re-clips itself. */
.mx-avatar--online,
.mx-avatar--away,
.mx-avatar--busy,
.mx-avatar--offline {
  position: relative;
  overflow: visible;
}
.mx-avatar--online img,
.mx-avatar--away img,
.mx-avatar--busy img,
.mx-avatar--offline img { border-radius: 50%; }
.mx-avatar--online::after,
.mx-avatar--away::after,
.mx-avatar--busy::after,
.mx-avatar--offline::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  width: 22%;
  min-width: 7px;
  max-width: 10px;
  aspect-ratio: 1;
  border-radius: 50%;
  box-shadow: 0 0 0 2px var(--mx-surface);
}
.mx-avatar--online::after  { background: var(--mx-green); }
.mx-avatar--away::after    { background: var(--mx-amber); }
.mx-avatar--busy::after    { background: var(--mx-red); }
.mx-avatar--offline::after { background: var(--mx-muted-2); }

.mx-avatar-group {
  display: inline-flex;
}
.mx-avatar-group .mx-avatar {
  box-shadow: 0 0 0 2px var(--mx-surface);
}
.mx-avatar-group .mx-avatar + .mx-avatar {
  margin-left: -8px;
}

/* ------------------------------------------------------------ 15 · Stat */
.mx-stat {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 18px 20px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  box-shadow: var(--mx-shadow-xs);
}
.mx-stat__label {
  font-size: var(--mx-text-xs);
  font-weight: 500;
  color: var(--mx-muted);
}
.mx-stat__value {
  font-size: 26px;
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.mx-stat__meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--mx-text-xs);
  color: var(--mx-muted);
}
.mx-stat__delta {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-weight: 600;
}
.mx-stat__delta--up   { color: var(--mx-green-fg); }
.mx-stat__delta--down { color: var(--mx-red-fg); }

/* ----------------------------------------------------------- 16 · Alert */
.mx-alert {
  display: flex;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius);
  background: var(--mx-surface);
  font-size: var(--mx-text-sm);
  color: var(--mx-ink-soft);
}
.mx-alert__icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  border-radius: 50%;
  font-size: 11px;
  font-weight: 700;
}
.mx-alert__title {
  margin: 0 0 1px;
  font-weight: 600;
  color: var(--mx-ink);
  letter-spacing: -0.006em;
}
.mx-alert--info    .mx-alert__icon { background: var(--mx-cyan-tint);  color: var(--mx-cyan-fg); }
.mx-alert--success .mx-alert__icon { background: var(--mx-green-tint); color: var(--mx-green-fg); }
.mx-alert--warning .mx-alert__icon { background: var(--mx-amber-tint); color: var(--mx-amber-fg); }
.mx-alert--danger  .mx-alert__icon { background: var(--mx-red-tint);   color: var(--mx-red-fg); }
.mx-alert--danger  { border-color: color-mix(in srgb, var(--mx-red) 28%, transparent); }
.mx-alert--warning { border-color: color-mix(in srgb, var(--mx-amber) 30%, transparent); }

/* ----------------------------------------------------------- 17 · Toast (Sonner-style)
   A stacked toaster: newest toast is the "front", older ones collapse behind it
   (scaled + lifted). Hovering the toaster expands the stack into real flow.
   Fire via the mxToast store — see mx-ui.js. Structure:
     .mx-toaster > ol.mx-toast-list > li.mx-toast > div.mx-toast__inner        */
.mx-toaster {
  position: fixed;
  z-index: 1100;
  width: var(--mx-toast-w, 356px);
  max-width: calc(100vw - 32px);
  --mx-toast-gap: 15px;         /* collapsed peek between stacked toasts        */
  --mx-toast-sgn: -1;           /* bottom positions lift older toasts up (-)    */
}
.mx-toaster[data-y="bottom"] { bottom: 26px; }
.mx-toaster[data-y="top"]    { top: 26px; --mx-toast-sgn: 1; }
.mx-toaster[data-x="right"]  { right: 26px; }
.mx-toaster[data-x="left"]   { left: 26px; }
.mx-toaster[data-x="center"] { left: 50%; transform: translateX(-50%); }

.mx-toast-list {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
}

/* Positioning shell — owns the stacking transform (translateY / scale). */
.mx-toast {
  position: absolute;
  left: 0;
  right: 0;
  box-sizing: border-box;
  opacity: 0;                                            /* enter start */
  transform: translateY(calc(var(--mx-toast-sgn) * -130%));
  transition:
    transform 0.45s var(--mx-ease-out),
    opacity   0.35s var(--mx-ease-out),
    height    0.35s var(--mx-ease-out);
  will-change: transform;
}
.mx-toaster[data-y="bottom"] .mx-toast { bottom: 0; transform-origin: center bottom; }
.mx-toaster[data-y="top"]    .mx-toast { top: 0;    transform-origin: center top; }

/* Collapsed (default): stacked + scaled behind the front toast. */
.mx-toaster:not([data-expanded]) .mx-toast[data-mounted] {
  opacity: 1;
  transform:
    translateY(calc(var(--index) * var(--mx-toast-gap) * var(--mx-toast-sgn)))
    scale(calc(1 - var(--index) * 0.055));
}
.mx-toaster:not([data-expanded]) .mx-toast:not(:last-child) {
  height: var(--front-h);        /* clip behind toasts to the front toast's box */
  overflow: hidden;
}
.mx-toaster:not([data-expanded]) .mx-toast[data-hidden] { opacity: 0; }

/* Expanded (hover / focus-within): real stacked flow, full height. */
.mx-toaster[data-expanded] .mx-toast[data-mounted] {
  opacity: 1;
  transform: translateY(calc(var(--offset) * var(--mx-toast-sgn)));
}

/* Exit. */
.mx-toast[data-removing] {
  opacity: 0 !important;
  transform: translateY(calc(var(--mx-toast-sgn) * -130%)) scale(0.9) !important;
}

/* The visible card. Also the swipe layer (translated on drag). */
.mx-toast__inner {
  position: relative;
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 14px 15px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  box-shadow: var(--mx-shadow-lg);
  font-size: var(--mx-text-sm);
  line-height: 1.45;
  touch-action: pan-y;
  transition: transform 0.2s var(--mx-ease-out), opacity 0.2s;
}
.mx-toast[data-swiping] .mx-toast__inner { transition: none; }

.mx-toast__icon {
  flex: 0 0 auto;
  margin-top: 1px;
  color: var(--mx-muted);
  display: block;
}
.mx-toast__icon svg { width: 18px; height: 18px; display: block; }
.mx-toast[data-type="success"] .mx-toast__icon { color: var(--mx-green); }
.mx-toast[data-type="error"]   .mx-toast__icon { color: var(--mx-red); }
.mx-toast[data-type="warning"] .mx-toast__icon { color: var(--mx-amber); }
.mx-toast[data-type="info"]    .mx-toast__icon { color: var(--mx-cyan); }

.mx-toast__spinner {
  display: inline-block;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--mx-line-strong);
  border-top-color: var(--mx-muted);
  animation: mx-spin 0.7s linear infinite;
}

.mx-toast__body { flex: 1 1 auto; min-width: 0; }
.mx-toast__title {
  margin: 0;
  font-weight: 600;
  color: var(--mx-ink);
  letter-spacing: -0.006em;
}
.mx-toast__desc {
  margin: 3px 0 0;
  color: var(--mx-muted);
}

.mx-toast__actions {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}
.mx-toast__btn {
  height: 26px;
  padding: 0 11px;
  border-radius: 7px;
  font-family: inherit;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  border: 1px solid transparent;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  transition: filter var(--mx-dur), background var(--mx-dur);
}
.mx-toast__btn:active { scale: 0.98; }
.mx-toast__btn--action { background: var(--mx-ink); color: var(--mx-bg); }
.mx-toast__btn--action:hover { filter: brightness(1.12); }
.mx-toast__btn--cancel { background: var(--mx-surface-strong); color: var(--mx-ink-soft); }
.mx-toast__btn--cancel:hover { background: var(--mx-line-strong); }

.mx-toast__close {
  position: absolute;
  /* INSIDE the card's top-right corner. The sonner-style chip that pokes past
     the edge floats over neighboring page content (topbar search) and reads
     as a stray glyph — keep the whole control within the toast. */
  top: 6px;
  right: 6px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: transparent;
  border: none;
  color: var(--mx-muted);
  display: grid;
  place-items: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s, color var(--mx-dur), background var(--mx-dur);
}
.mx-toast__close svg { width: 12px; height: 12px; }
.mx-toast__close:hover { color: var(--mx-ink); background: var(--mx-surface-strong); }
.mx-toast:hover .mx-toast__close,
.mx-toaster[data-expanded] .mx-toast:last-child .mx-toast__close { opacity: 1; }

/* richColors — tint the whole card by type. */
.mx-toast[data-rich][data-type="success"] .mx-toast__inner {
  background: var(--mx-green-tint);
  border-color: color-mix(in srgb, var(--mx-green) 32%, transparent);
}
.mx-toast[data-rich][data-type="success"] .mx-toast__title { color: var(--mx-green-fg); }
.mx-toast[data-rich][data-type="success"] .mx-toast__desc  { color: color-mix(in srgb, var(--mx-green-fg) 80%, transparent); }
.mx-toast[data-rich][data-type="error"] .mx-toast__inner {
  background: var(--mx-red-tint);
  border-color: color-mix(in srgb, var(--mx-red) 32%, transparent);
}
.mx-toast[data-rich][data-type="error"] .mx-toast__title { color: var(--mx-red-fg); }
.mx-toast[data-rich][data-type="error"] .mx-toast__desc  { color: color-mix(in srgb, var(--mx-red-fg) 80%, transparent); }
.mx-toast[data-rich][data-type="warning"] .mx-toast__inner {
  background: var(--mx-amber-tint);
  border-color: color-mix(in srgb, var(--mx-amber) 34%, transparent);
}
.mx-toast[data-rich][data-type="warning"] .mx-toast__title { color: var(--mx-amber-fg); }
.mx-toast[data-rich][data-type="warning"] .mx-toast__desc  { color: color-mix(in srgb, var(--mx-amber-fg) 80%, transparent); }
.mx-toast[data-rich][data-type="info"] .mx-toast__inner {
  background: var(--mx-cyan-tint);
  border-color: color-mix(in srgb, var(--mx-cyan) 32%, transparent);
}
.mx-toast[data-rich][data-type="info"] .mx-toast__title { color: var(--mx-cyan-fg); }
.mx-toast[data-rich][data-type="info"] .mx-toast__desc  { color: color-mix(in srgb, var(--mx-cyan-fg) 80%, transparent); }

@media (prefers-reduced-motion: reduce) {
  .mx-toast { transition: opacity 0.2s linear; }
  .mx-toast[data-mounted] { transform: none !important; }
  .mx-toast__inner { transition: opacity 0.2s linear; }
}

/* -------------------------------------------------------- 18 · Progress */
.mx-progress {
  height: 6px;
  border-radius: var(--mx-radius-pill);
  background: var(--mx-surface-strong);
  overflow: hidden;
}
.mx-progress__bar {
  height: 100%;
  border-radius: inherit;
  background: var(--mx-brand);
  transition: width 0.5s var(--mx-ease-out);
}
.mx-progress--success .mx-progress__bar { background: var(--mx-green); }
.mx-progress--warning .mx-progress__bar { background: var(--mx-amber); }
.mx-progress--danger  .mx-progress__bar { background: var(--mx-red); }

/* -------------------------------------------------------- 19 · Skeleton */
.mx-skeleton {
  position: relative;
  border-radius: var(--mx-radius-sm);
  background: var(--mx-surface-strong);
  overflow: hidden;
}
.mx-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent,
    color-mix(in srgb, var(--mx-surface) 60%, transparent),
    transparent
  );
  animation: mx-shimmer 1.6s infinite;
}
@keyframes mx-shimmer {
  from { translate: -100% 0; }
  to   { translate: 100% 0; }
}
.mx-skeleton--text   { height: 12px; }
.mx-skeleton--circle { border-radius: 50%; }
@media (prefers-reduced-motion: reduce) {
  .mx-skeleton::after { animation: none; }
}

/* --------------------------------------------------------- 20 · Spinner */
/* ── Layout utilities ────────────────────────────────────────────────────────
   MX-native display/flex helpers. These replaced the retired Bootstrap
   utilities app-wide (d-none→mx-hide, d-flex→mx-flex, … renamed 2026-07-22);
   the markup + JS that authored them is live (drawers, review column picker,
   dropzone toggles, notif dot). Keep this the ONLY utility vocabulary. */
.mx-hide { display: none !important; }
.mx-block { display: block !important; }
.mx-inline { display: inline !important; }
.mx-flex { display: flex !important; }
.mx-iflex { display: inline-flex !important; }
.mx-flex--col { flex-direction: column !important; }
.mx-flex--wrap { flex-wrap: wrap !important; }
.mx-grow { flex-grow: 1 !important; }
.mx-shrink { flex-shrink: 1 !important; }
.mx-noshrink { flex-shrink: 0 !important; }
.mx-ai-center { align-items: center !important; }
.mx-ai-start { align-items: flex-start !important; }
.mx-ai-end { align-items: flex-end !important; }
.mx-ai-stretch { align-items: stretch !important; }
.mx-jc-between { justify-content: space-between !important; }
.mx-jc-center { justify-content: center !important; }
.mx-jc-end { justify-content: flex-end !important; }
.mx-jc-start { justify-content: flex-start !important; }
.mx-nowrap { white-space: nowrap !important; }
/* Responsive (defined after .mx-hide so they win when paired with it) */
@media (min-width: 576px) { .mx-sm-inline { display: inline !important; } }
@media (min-width: 768px) { .mx-md-row { flex-direction: row !important; } }

.mx-spinner {
  display: inline-block;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--mx-line-strong);
  border-top-color: var(--mx-brand);
  animation: mx-spin 0.7s linear infinite;
}
.mx-spinner--sm { width: 14px; height: 14px; border-width: 1.5px; }
.mx-spinner--lg { width: 26px; height: 26px; }

/* Loading overlay (window.mxBlock/mxUnblock) — native replacement for the Sneat
   plugin de block-ui. Keep this separate from the .mx-block display utility.
   .mx-loading-overlay covers its host element; .mx-loading-overlay--fixed
   covers the whole viewport for full-page "generating…" states. */
.mx-loading-overlay {
  position: absolute;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--mx-surface) 80%, transparent);
}
.mx-loading-overlay--fixed {
  position: fixed;
  z-index: 20000;
  background: rgba(15, 23, 42, 0.72);
  backdrop-filter: blur(2px);
}
.mx-loading-overlay__content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
}

/* Transitional structure for server-rendered controls already moved to
   data-mx-toggle. The behavior comes from mx-ui.js. */
.mx .tab-pane:not(.active) { display: none; }
.mx .collapse:not(.show) { display: none; }
.mx .dropdown { position: relative; }
.mx .dropdown-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 940;
  display: none;
  min-width: 180px;
  padding: 6px;
  margin: 0;
  list-style: none;
  color: var(--mx-ink);
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius);
  box-shadow: var(--mx-shadow-lg);
}
.mx .dropdown-menu.show { display: block; }
.mx .dropdown-menu-end { right: 0; left: auto; }
.mx .dropdown-item {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  color: var(--mx-ink-soft);
  text-decoration: none;
  border: 0;
  border-radius: var(--mx-radius-sm);
  background: transparent;
  cursor: pointer;
}
.mx .dropdown-item:hover,
.mx .dropdown-item:focus-visible { color: var(--mx-ink); background: var(--mx-surface-strong); outline: none; }

/* Transitional overlay structure for server-rendered forms. Behavior comes
   from MxModal/MxOffcanvas while their inner markup moves to native MX pieces. */
body.mx-overlay-open { overflow: hidden; }
.mx-runtime-modal,
.modal {
  position: fixed;
  inset: 0;
  z-index: 1090;
  display: none;
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  outline: 0;
}
.mx-runtime-modal.show,
.modal.show { display: block; }
/* No enter animation on runtime-modal content: a keyframe fade with fill-mode
   `both` left the card stuck at opacity:0 (invisible) whenever the animation
   didn't run (e.g. paused/background tab, reduced-motion). The dialog now appears
   solid instantly — guaranteed visible, no transparency edge cases. */
.mx-runtime-modal__dialog,
.modal-dialog {
  box-sizing: border-box;
  position: relative;
  width: calc(100% - 32px);
  max-width: 540px;
  margin: 28px auto;
  padding: 0;
  pointer-events: none;
}
.mx-runtime-modal__dialog--centered,
.modal-dialog-centered { display: flex; align-items: center; justify-content: center; min-height: calc(100% - 56px); }
/* Delete confirmation modal — center with grid place-items instead of the
   flex + min-height + `margin:28px auto` combo, which reflowed on open and made
   the card appear centered then jump up ("sale en el centro y luego sube").
   Grid centering has no margin/min-height, so the card cannot shift. Scoped to
   #deletemodal so every delete dialog across the app centers identically. */
/* ── NORMA: delete / confirm dialogs always center ──────────────────────────
   Two ways in: the content is a canonical delete (`.mx-modal--alert`, from
   _mx_delete_dialog.html) — works no matter which `#dialog-*` hosts it, no
   per-container class needed — OR the dialog opts in with `--centered`.
   Centering is `position:fixed + inset:0 + margin:auto` on the dialog — NOT flex
   on the shell keyed to `.show`. That matters on CLOSE: MxModal.hide() removes
   `.show` 180ms before it sets `display:none`, and a `.show`-keyed flex-centering
   vanished during that gap, dropping the card to `margin:28px auto` — so on Cancel
   the card jumped to the TOP, then disappeared. Fixed centering is independent of
   the shell's display/`.show`, so the card stays put through open AND close, and
   tall content scrolls (max-height) instead of clipping. */
.mx-runtime-modal:has(.mx-modal--alert) > .mx-runtime-modal__dialog {
  position: fixed; inset: 0; margin: auto;
  width: fit-content; height: fit-content; min-height: 0;
  max-width: min(440px, calc(100vw - 32px)); max-height: calc(100vh - 32px);
  overflow: auto;   /* tall content scrolls instead of clipping (short deletes: no scrollbar) */
}
.mx-runtime-modal > .mx-runtime-modal__dialog--centered {
  position: fixed; inset: 0; margin: auto;
  height: fit-content; min-height: 0; max-height: calc(100vh - 32px);
  overflow: auto;   /* fixed pos escapes the shell's scroll, so scroll here (tall issue-modal forms) */
}
.mx-runtime-modal__dialog--scrollable,
.modal-dialog-scrollable { height: calc(100% - 56px); }
.mx-runtime-modal__dialog--scrollable .mx-modal,
.mx-runtime-modal__dialog--scrollable .mx-runtime-modal__content,
.mx-runtime-modal__dialog--scrollable .modal-content,
.modal-dialog-scrollable .modal-content { max-height: 100%; overflow: hidden; }
.mx-runtime-modal__dialog--scrollable .mx-modal__body,
.mx-runtime-modal__dialog--scrollable .mx-runtime-modal__body,
.mx-runtime-modal__dialog--scrollable .modal-body,
.modal-dialog-scrollable .modal-body { overflow-y: auto; min-height: 0; }
/* When body+footer are wrapped in a <form> (Django modals), the form must relay
   the content's flex column so the body can shrink+scroll and the footer stays put. */
.mx-runtime-modal__dialog--scrollable .mx-runtime-modal__content > form,
.modal-dialog-scrollable .modal-content > form {
  display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;
}
.mx-runtime-modal__dialog--scrollable .mx-runtime-modal__footer,
.modal-dialog-scrollable .modal-footer { flex: 0 0 auto; }
/* A native .mx-modal fragment is narrower than its runtime dialog wrapper
   (mx-modal--xl 880 vs __dialog--xl 1080); with width:100% + max-width it
   hugs the wrapper's left edge — keep it centered. */
.mx-runtime-modal__dialog .mx-modal { margin-inline: auto; }
/* The runtime wrapper carries 28px top+bottom margins (56 total): cap the
   scroll shells to fit, or the container grows a stray scrollbar that also
   knocks the modal off-center. */
.mx-runtime-modal__dialog .mx-modal--scroll,
.mx-runtime-modal__dialog .mx-modal--sticky { max-height: calc(100dvh - 56px); }
.mx-runtime-modal__content,
.modal-content {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  pointer-events: auto;
  color: var(--mx-ink);
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  box-shadow: var(--mx-shadow-xl);
  outline: 0;
}
.mx-runtime-modal__header,
.mx-runtime-modal__footer,
.modal-header,
.modal-footer { display: flex; align-items: center; padding: 16px 20px; }
.mx-runtime-modal__header,
.modal-header { justify-content: space-between; border-bottom: 1px solid var(--mx-line); }
.mx-runtime-modal__footer,
.modal-footer { justify-content: flex-end; gap: 8px; border-top: 1px solid var(--mx-line); }
.mx-runtime-modal__body,
.modal-body { position: relative; flex: 1 1 auto; padding: 20px; }
.mx-runtime-modal__title,
.modal-title {
  margin: 0;
  font-size: var(--mx-text-lg);
  font-weight: 600;
  line-height: 1.25;
  color: var(--mx-ink);
  letter-spacing: -0.014em;
}
.mx-runtime-modal__close,
.btn-close {
  width: 30px;
  height: 30px;
  padding: 0;
  flex: 0 0 30px;
  font-size: 0;
  background: transparent
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E")
    no-repeat center;
  border: 0;
  border-radius: var(--mx-radius-sm);
  cursor: pointer;
}
.mx-runtime-modal__close:hover,
.btn-close:hover { background-color: var(--mx-surface-strong); }
.mx-runtime-modal__close:focus-visible,
.btn-close:focus-visible { outline: 2px solid var(--mx-brand); outline-offset: 2px; }
.mx-runtime-modal .mx-runtime-modal__dialog,
.modal.fade .modal-dialog { transform: translateY(-10px) scale(.985); transition: transform .18s ease; }
.mx-runtime-modal.show .mx-runtime-modal__dialog,
.modal.show .modal-dialog { transform: none; }
.mx-overlay-backdrop,
.modal-backdrop,
.offcanvas-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1080;
  background: rgba(15, 23, 42, .48);
  opacity: 0;
  transition: opacity .18s ease;
}
.mx-overlay-backdrop.show,
.modal-backdrop.show,
.offcanvas-backdrop.show { opacity: 1; }
.mx-runtime-offcanvas,
.offcanvas {
  position: fixed;
  z-index: 1090;
  display: flex;
  flex-direction: column;
  max-width: 100%;
  color: var(--mx-ink);
  visibility: hidden;
  background: var(--mx-surface);
  box-shadow: var(--mx-shadow-xl);
  transition: transform .2s ease, visibility .2s ease;
}
.mx-runtime-offcanvas--start,
.mx-runtime-offcanvas--end,
.offcanvas-start,
.offcanvas-end { top: 0; bottom: 0; width: var(--mx-drawer-w, min(440px, calc(100vw - 24px))); }
.mx-runtime-offcanvas--start,
.offcanvas-start { left: 0; transform: translateX(-100%); border-right: 1px solid var(--mx-line); }
.mx-runtime-offcanvas--end,
.offcanvas-end { right: 0; transform: translateX(100%); border-left: 1px solid var(--mx-line); }
.mx-runtime-offcanvas--top,
.mx-runtime-offcanvas--bottom,
.offcanvas-top,
.offcanvas-bottom { right: 0; left: 0; max-height: 100%; }
.mx-runtime-offcanvas--top,
.offcanvas-top { top: 0; transform: translateY(-100%); border-bottom: 1px solid var(--mx-line); }
.mx-runtime-offcanvas--bottom,
.offcanvas-bottom { bottom: 0; transform: translateY(100%); border-top: 1px solid var(--mx-line); }
.mx-runtime-offcanvas.show,
.offcanvas.show { visibility: visible; transform: none; }
.mx-runtime-offcanvas__header,
.offcanvas-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--mx-line); }
.mx-runtime-offcanvas__body,
.offcanvas-body { flex: 1 1 auto; padding: 20px; overflow-y: auto; }
.mx-runtime-offcanvas__footer,
.offcanvas-footer { display: flex; justify-content: flex-end; gap: 8px; padding: 14px 20px; border-top: 1px solid var(--mx-line); }
.mx-runtime-offcanvas__title,
.offcanvas-title { margin: 0; font-size: var(--mx-text-md); font-weight: 600; letter-spacing: -0.011em; }
.mx-date-range-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  padding: 8px;
  border-top: 1px solid var(--mx-line);
}
.mx-date-range-preset {
  padding: 5px 8px;
  color: var(--mx-ink-soft);
  font: inherit;
  font-size: var(--mx-text-xs);
  background: var(--mx-surface-soft);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-sm);
  cursor: pointer;
}
.mx-date-range-preset:hover,
.mx-date-range-preset:focus-visible { color: var(--mx-ink); border-color: var(--mx-line-strong); outline: none; }
@media (min-width: 576px) {
  .mx-runtime-modal__dialog--sm,
  .modal-dialog.modal-sm { max-width: 420px; }
  .mx-runtime-modal__dialog--md,
  .modal-dialog.modal-md { max-width: 560px; }
}
@media (min-width: 992px) {
  .mx-runtime-modal__dialog--lg,
  .modal-dialog.modal-lg { max-width: 800px; }
  .mx-runtime-modal__dialog--xl,
  .modal-dialog.modal-xl { max-width: 1080px; }
}

.mx-collapse:not(.show) { display: none; }
/* Tooltip bubble — rendered at <body> level by mx-ui.js (mxTooltip) with position:fixed,
   so it can NEVER be clipped by an ancestor's overflow:hidden / overflow-x:clip (cards,
   scrollable tables). The previous ::after/::before implementation was a pseudo-element,
   i.e. part of the trigger's OWN box, so it could not escape those containers — that was a
   recurring app-wide bug. Authoring API is unchanged: data-mx-tip="text" (empty = none),
   optional .mx-tip--wide for multi-line copy. .mx-tip--end is obsolete — the engine now
   clamps to the viewport and flips above/below automatically. */
.mx-tip {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2147483000;
  padding: 5px 9px;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  letter-spacing: -0.003em;
  line-height: 1.35;
  white-space: nowrap;
  color: var(--mx-bg);
  background: var(--mx-ink);
  border-radius: var(--mx-radius-sm);
  box-shadow: var(--mx-shadow-md);
  opacity: 0;
  pointer-events: none;
  translate: 0 2px;
  transition: opacity var(--mx-dur) var(--mx-ease-out),
    translate var(--mx-dur) var(--mx-ease-out);
}
.mx-tip.is-visible { opacity: 1; translate: 0 0; }
.mx-tip--multiline { white-space: pre-line; text-align: left; }
.mx-tip__arrow { position: absolute; width: 0; height: 0; border: 5px solid transparent; }
.mx-tip[data-placement="top"] .mx-tip__arrow { top: 100%; border-top-color: var(--mx-ink); }
.mx-tip[data-placement="bottom"] .mx-tip__arrow { bottom: 100%; border-bottom-color: var(--mx-ink); }

/* charts: sibling dimming on hover */
.mx-bars:hover .mx-bars__bar {
  opacity: 0.4;
}
.mx-bars .mx-bars__col:hover .mx-bars__bar {
  opacity: 1;
}

/* ------------------------------------------------------------- 22 · Kbd */
.mx-kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  font-family: var(--mx-font);
  font-size: 11px;
  font-weight: 500;
  color: var(--mx-muted);
  background: var(--mx-surface);
  border: 1px solid var(--mx-line-strong);
  border-bottom-width: 2px;
  border-radius: 5px;
}

/* ------------------------------------------------------- 23 · Separator */
.mx-separator {
  border: none;
  height: 1px;
  background: var(--mx-line);
  margin: var(--mx-gap-4) 0;
}
.mx-separator--label {
  display: flex;
  align-items: center;
  gap: var(--mx-gap-3);
  height: auto;
  background: none;
  font-size: var(--mx-text-xs);
  color: var(--mx-muted-2);
}
.mx-separator--label::before,
.mx-separator--label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--mx-line);
}

/* ----------------------------------------------------- 24 · Empty state */
.mx-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 40px 24px;
  text-align: center;
  border: 1px dashed var(--mx-line-strong);
  border-radius: var(--mx-radius-lg);
}
.mx-empty[hidden] { display: none !important; }
.mx-empty__icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-bottom: 8px;
  border-radius: var(--mx-radius);
  background: var(--mx-surface-strong);
  color: var(--mx-muted);
  font-size: 17px;
}
.mx-empty__title {
  margin: 0;
  font-size: var(--mx-text-sm);
  font-weight: 600;
  letter-spacing: -0.006em;
}
.mx-empty__desc {
  margin: 0;
  font-size: var(--mx-text-sm);
  color: var(--mx-muted);
  max-width: 300px;
}
.mx-empty .mx-btn {
  margin-top: 12px;
}
/* Lucide SVG icon inside the empty-state chip (list = inbox, search = magnifier) */
.mx-empty__icon svg { width: 20px; height: 20px; }
/* Compact variant — for empty states inside a card / dropdown / small widget
   (drops the dashed frame + tightens spacing). */
.mx-empty--sm {
  padding: 24px 16px;
  border: none;
  border-radius: var(--mx-radius);
}
.mx-empty--sm .mx-empty__icon { width: 34px; height: 34px; margin-bottom: 6px; font-size: 15px; }
.mx-empty--sm .mx-empty__icon svg { width: 17px; height: 17px; }

/* ---------------------------------------------------------- 25 · Dialog */
.mx-modal-scrim {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  padding: var(--mx-gap-4);
  background: var(--mx-scrim);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
/* Scrim enter/leave (use INSTEAD of x-transition.opacity): Chromium doesn't
   modulate backdrop-filter by opacity, so an opacity-only fade leaves the
   blur at full strength and it snaps off at display:none (full-page blink).
   These classes animate opacity AND the blur together:
     x-transition:enter="mx-scrim-enter"  x-transition:enter-start="mx-scrim-enter-start"
     x-transition:leave="mx-scrim-leave"  x-transition:leave-end="mx-scrim-leave-end"   */
.mx-scrim-enter,
.mx-scrim-leave {
  transition: opacity 0.18s ease, backdrop-filter 0.18s ease,
    -webkit-backdrop-filter 0.18s ease;
}
.mx-scrim-enter-start,
.mx-scrim-leave-end {
  opacity: 0;
  backdrop-filter: blur(0px);
  -webkit-backdrop-filter: blur(0px);
}
.mx-modal {
  position: relative;
  width: 100%;
  max-width: 420px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-xl);
  box-shadow: var(--mx-shadow-lg);
  overflow: hidden;
}
/* Size scale — pick one per dialog; default (no modifier) = 420px. */
.mx-modal--sm { max-width: 400px; }
.mx-modal--md { max-width: 520px; }
.mx-modal--lg { max-width: 680px; }
.mx-modal--xl { max-width: 880px; }
.mx-modal__header {
  padding: 20px 22px 0;
}
.mx-modal__title {
  margin: 0;
  font-size: var(--mx-text-lg);
  font-weight: 600;
  line-height: 1.25; /* self-contained: host heading styles must not leak in */
  color: var(--mx-ink);
  letter-spacing: -0.014em;
}
.mx-modal__desc {
  margin: 4px 0 0;
  font-size: var(--mx-text-sm);
  line-height: 1.45;
  color: var(--mx-muted);
}
.mx-modal__body {
  padding: 14px 22px 20px;
  font-size: var(--mx-text-sm);
  color: var(--mx-ink-soft);
}
.mx-modal__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--mx-gap-2);
  padding: 14px 22px;
  border-top: 1px solid var(--mx-line);
  background: var(--mx-surface-soft);
}

/* ---------------------------------------------------------- 26 · Drawer */
.mx-drawer-scrim {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--mx-scrim);
  backdrop-filter: blur(3px);
}
/* Drawer / sheet — slides in from any of the four edges (shadcn "position").
   Side is chosen with a modifier: --right (default) · --left · --top · --bottom.
   A single pair of CSS vars (--mx-drawer-tx/ty) carries the off-screen offset so
   ONE transition class set animates every side (see .mx-slide-* below). */
/* Base = the RIGHT drawer (a bare .mx-drawer slides in from the right). Every
   other side FULLY resets what differs — including the off-screen offset vars —
   so no right-side geometry leaks onto left/top/bottom. */
.mx-drawer {
  position: fixed;
  z-index: 1001;
  display: flex;
  flex-direction: column;
  background: var(--mx-surface);
  box-shadow: var(--mx-shadow-lg);
  --mx-drawer-w: min(380px, calc(100vw - 32px));
  --mx-drawer-tx: 100%;
  --mx-drawer-ty: 0;
  top: 0;
  right: 0;
  bottom: 0;
  left: auto;
  width: var(--mx-drawer-w);
  border-left: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-xl) 0 0 var(--mx-radius-xl);
}
/* .mx-drawer--right is an explicit alias of the base — no overrides needed. */
.mx-drawer--left {
  right: auto;
  left: 0;
  border-left: none;
  border-right: 1px solid var(--mx-line);
  border-radius: 0 var(--mx-radius-xl) var(--mx-radius-xl) 0;
  --mx-drawer-tx: -100%;
}
/* ---- Sheet drawers (top/bottom): full width, self-size to content ---------- */
.mx-drawer--top,
.mx-drawer--bottom {
  left: 0;
  right: 0;
  width: auto;
  max-height: calc(100dvh - 6rem);
  border-left: none;
  --mx-drawer-tx: 0;
}
.mx-drawer--top {
  top: 0;
  bottom: auto;
  border-bottom: 1px solid var(--mx-line);
  border-radius: 0 0 var(--mx-radius-xl) var(--mx-radius-xl);
  --mx-drawer-ty: -100%;
}
.mx-drawer--bottom {
  top: auto;
  bottom: 0;
  border-top: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-xl) var(--mx-radius-xl) 0 0;
  --mx-drawer-ty: 100%;
}
/* Size variants set the width of SIDE drawers only (top/bottom stay full-width
   and auto-size). md = single-column forms, lg = detail, xl = tables/preview. */
.mx-drawer--md { --mx-drawer-w: min(440px, calc(100vw - 32px)); }
.mx-drawer--lg { --mx-drawer-w: min(560px, calc(100vw - 32px)); }
.mx-drawer--xl { --mx-drawer-w: min(720px, calc(100vw - 32px)); }
/* Swipe handle — a subtle grip on the exposed edge (shadcn showSwipeHandle).
   Rendered for top/bottom sheets by default; opt-in for side drawers. */
.mx-drawer__handle {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px 0 2px;
}
.mx-drawer__handle::before {
  content: "";
  width: 44px;
  height: 5px;
  border-radius: var(--mx-radius-pill);
  background: var(--mx-line-strong, var(--mx-line));
}
/* Top sheet: handle sits on the exposed (bottom) edge */
.mx-drawer--top .mx-drawer__handle { order: 1; padding: 2px 0 10px; }
/* Side drawers: vertical grip on the exposed edge */
.mx-drawer--left .mx-drawer__handle,
.mx-drawer--right .mx-drawer__handle {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  padding: 0;
}
.mx-drawer--left .mx-drawer__handle { right: 8px; }
.mx-drawer--right .mx-drawer__handle { left: 8px; }
.mx-drawer--left .mx-drawer__handle::before,
.mx-drawer--right .mx-drawer__handle::before { width: 5px; height: 44px; }
.mx-drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--mx-gap-3);
  padding: 18px 20px;
  border-bottom: 1px solid var(--mx-line);
}
.mx-drawer__title {
  margin: 0;
  font-size: var(--mx-text-md);
  font-weight: 600;
  letter-spacing: -0.011em;
}
.mx-drawer__body {
  flex: 1;
  min-height: 0; /* allow the flex child to shrink so overflow-y actually scrolls */
  overflow-y: auto;
  padding: 20px;
  font-size: var(--mx-text-sm);
  color: var(--mx-ink-soft);
}
.mx-drawer__footer {
  display: flex;
  gap: var(--mx-gap-2);
  padding: 14px 20px;
  border-top: 1px solid var(--mx-line);
}

/* transition helpers (Alpine x-transition classes) */
/* Drawer slide — off-screen offset comes from --mx-drawer-tx/ty on the panel,
   so the same classes slide a drawer in from whichever side its modifier picks. */
.mx-slide-enter        { transition: transform var(--mx-dur-slow) var(--mx-ease-out); }
.mx-slide-enter-start  { transform: translate(var(--mx-drawer-tx), var(--mx-drawer-ty)); }
.mx-slide-leave        { transition: transform var(--mx-dur-slow) var(--mx-ease-out); }
.mx-slide-leave-end    { transform: translate(var(--mx-drawer-tx), var(--mx-drawer-ty)); }
.mx-pop-enter          { transition: transform var(--mx-dur) var(--mx-ease-out), opacity var(--mx-dur); }
.mx-pop-enter-start    { transform: scale(0.97); opacity: 0; }
.mx-pop-leave          { transition: transform var(--mx-dur-fast), opacity var(--mx-dur-fast); }
.mx-pop-leave-end      { transform: scale(0.97); opacity: 0; }

/* -------------------------------------------------------- 27 · Dropdown */
.mx-dropdown {
  position: relative;
  display: inline-block;
}
.mx-dropdown__menu {
  position: absolute;
  top: calc(100% + 5px);
  left: 0;
  z-index: 900;
  min-width: 190px;
  padding: 4px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  box-shadow: var(--mx-shadow-md);
  transform-origin: top left;
}
.mx-dropdown__menu--end {
  left: auto;
  right: 0;
  transform-origin: top right;
}
.mx-dropdown__menu--up {
  top: auto;
  bottom: calc(100% + 5px);
  transform-origin: bottom left;
}
.mx-dropdown__label {
  padding: 7px 10px 4px;
  font-size: 11px;
  font-weight: 500;
  color: var(--mx-muted-2);
}
.mx-dropdown__item {
  -webkit-appearance: none;
  appearance: none;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 7px 10px;
  font: inherit;
  font-size: var(--mx-text-sm);
  color: var(--mx-ink-soft);
  background: none;
  border: none;
  border-radius: var(--mx-radius-sm);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--mx-dur-fast), color var(--mx-dur-fast);
}
.mx-dropdown__item:hover {
  background: var(--mx-surface-strong);
  color: var(--mx-ink);
}
.mx-dropdown__item--danger { color: var(--mx-red-fg); }
.mx-dropdown__item--danger:hover { background: var(--mx-red-tint); color: var(--mx-red-fg); }
.mx-dropdown__item .mx-kbd { margin-left: auto; }
.mx-dropdown__sep {
  height: 1px;
  margin: 4px 6px;
  background: var(--mx-line);
}

/* ------------------------------------------------------ 28 · Breadcrumb */
.mx-breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--mx-text-sm);
  color: var(--mx-muted);
}
.mx-breadcrumb a {
  color: inherit;
  text-decoration: none;
  transition: color var(--mx-dur-fast);
}
.mx-breadcrumb a:hover {
  color: var(--mx-ink);
}
.mx-breadcrumb__sep {
  color: var(--mx-muted-2);
  font-size: 11px;
  user-select: none;
}
.mx-breadcrumb__current {
  color: var(--mx-ink);
  font-weight: 500;
}

/* ------------------------------------------------------ 29 · Pagination */
.mx-pagination {
  display: flex;
  align-items: center;
  gap: 4px;
}
.mx-pagination__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--mx-h-sm);
  height: var(--mx-h-sm);
  padding: 0 6px;
  font: inherit;
  font-size: var(--mx-text-sm);
  color: var(--mx-ink-soft);
  background: none;
  border: none;
  border-radius: var(--mx-radius-sm);
  cursor: pointer;
  text-decoration: none;
  transition: background var(--mx-dur-fast), color var(--mx-dur-fast);
}
.mx-pagination__item:hover {
  background: var(--mx-surface-strong);
}
.mx-pagination__item.is-active {
  background: var(--mx-surface);
  border: 1px solid var(--mx-line-strong);
  box-shadow: var(--mx-shadow-xs);
  font-weight: 500;
  color: var(--mx-ink);
}
.mx-pagination__item[disabled] {
  opacity: 0.4;
  pointer-events: none;
}
.mx-pagination__ellipsis {
  min-width: var(--mx-h-sm);
  text-align: center;
  color: var(--mx-muted-2);
}
/* labelled Previous / Next (text + chevron) */
.mx-pagination__item--label { gap: 4px; padding: 0 11px; }
.mx-pagination__item--label svg { width: 15px; height: 15px; }
/* full-width bar layout — meta on the left, controls on the right */
.mx-pagination--bar {
  width: 100%;
  justify-content: space-between;
}
.mx-pagination__meta {
  font-size: var(--mx-text-sm);
  color: var(--mx-muted);
}

/* List/table pagination bar — SaaS-wide standard (promoted from mx-reimbursement).
   Use inside any list card: .mxe-pagination wraps a left group (.mxe-page-size
   select + .mx-pagination__meta) and .mxe-pagination__controls (the page links). */
.mxe-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--mx-gap-3);
  flex-wrap: wrap;
  border-top: 1px solid var(--mx-line);
  padding: 12px 20px;
  background: transparent;
}
.mxe-pagination__controls {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.mx-pagination a.mx-pagination__item { text-decoration: none; cursor: pointer; }
.mx-pagination__item.is-disabled { opacity: 0.4; pointer-events: none; }
/* Native <dialog> styled as an MX modal — framework-free (works in HTMX-swapped
   content where Alpine directives don't bind). Use dialog.showModal()/close(). */
dialog.mx-dialog { border: 0; padding: 0; background: transparent; max-width: min(440px, calc(100vw - 32px)); color: var(--mx-ink); overflow: visible; }
dialog.mx-dialog::backdrop { background: rgba(15, 23, 42, .45); backdrop-filter: blur(2px); }
dialog.mx-dialog[open] { animation: mx-dialog-in .16s var(--mx-ease-out, ease); }
@keyframes mx-dialog-in { from { opacity: 0; transform: translateY(6px) scale(.98); } to { opacity: 1; transform: none; } }

/* Thin, subtle horizontal scrollbar for table scroll containers. */
.mx-scroll-x { scrollbar-width: thin; scrollbar-color: var(--mx-line-strong, rgba(100,116,139,.35)) transparent; }
.mx-scroll-x::-webkit-scrollbar { height: 8px; width: 8px; }
.mx-scroll-x::-webkit-scrollbar-track { background: transparent; }
.mx-scroll-x::-webkit-scrollbar-thumb { background: var(--mx-line-strong, rgba(100,116,139,.35)); border-radius: 999px; border: 2px solid transparent; background-clip: padding-box; }
.mx-scroll-x:hover::-webkit-scrollbar-thumb { background: var(--mx-muted-2, rgba(100,116,139,.55)); background-clip: padding-box; }
.mxe-page-size {
  width: 72px;
  height: var(--mx-h-sm);
  padding: 0 24px 0 9px;
  font-size: var(--mx-text-sm);
  border-radius: var(--mx-radius-sm);
  background-position: right 7px center;
  background-size: 11px;
}
/* Filter-count pill inside the Filter toggle button (SaaS-wide standard). */
.mxe-filter-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--mx-radius-pill, 999px);
  background: var(--mx-brand);
  color: var(--mx-on-brand, #fff);
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
}
.mxe-filter-count:empty { display: none; }
.mxe-pagination .mx-pagination__meta { white-space: nowrap; }
/* Edge-align table cells with the 20px card padding (toolbar / pagination). */
.mxe-table th:first-child, .mxe-table td:first-child { padding-left: 20px; }
.mxe-table th:last-child,  .mxe-table td:last-child  { padding-right: 20px; }

/* ------------------------------------------------------- 30 · Utilities */
.mx-stack  { display: flex; flex-direction: column; gap: var(--mx-gap-4); }
.mx-row    { display: flex; align-items: center; gap: var(--mx-gap-3); }
.mx-row--between { justify-content: space-between; }
.mx-muted  { color: var(--mx-muted); }
.mx-spread { flex: 1; }


/* Django adapter: the real <select>/<input> backing an MX combobox/date picker
   stays in the form (for submission) but is hidden — the MX control mirrors it.
   Global (not scoped to .mx-form): runtime pickers (mxEnhanceDate/mxEnhanceRange)
   also mount in bare drawer shells with no .mx-form ancestor — e.g. the Time Off
   request drawer — where the raw native input was leaking beside the MX trigger.
   The class is only ever applied to a control the MX picker has already replaced. */
.mx-native-select, .mx-native-input { display: none; }
/* The combobox adapters (_mx_combobox_multi/single) always wrap in .mx-cbx-field —
   hide the mirrored native control regardless of an .mx-form ancestor (modals
   loaded into bare shells were leaking the raw <select multiple>). */
.mx-cbx-field .mx-native-select, .mx-cbx-field .mx-native-input { display: none !important; }

/* ==========================================================================
   v0.3 additions — full shadcn parity
   31 Toggle/Group     32 Collapsible     33 Aspect ratio   34 Scroll area
   35 Popover          36 Hover card      37 Alert dialog   38 Input group
   39 Input OTP        40 Combobox        41 Command        42 Context menu
   43 Menubar          44 Calendar        45 Carousel       46 Data table
   47 Resizable        48 Chart           49 Sidebar
   ========================================================================== */

/* ---------------------------------------------------- 31 · Toggle/Group */
.mx-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: var(--mx-h-sm);
  min-width: var(--mx-h-sm);
  padding: 0 10px;
  font: inherit;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  color: var(--mx-muted);
  background: transparent;
  border: none;
  border-radius: var(--mx-radius-sm);
  cursor: pointer;
  transition: background var(--mx-dur-fast), color var(--mx-dur-fast);
}
.mx-toggle:hover {
  background: var(--mx-surface-strong);
  color: var(--mx-ink-soft);
}
.mx-toggle[aria-pressed="true"],
.mx-toggle.is-on,
.mx-toggle:has(input:checked) {
  background: var(--mx-brand-tint);
  color: var(--mx-brand-fg);
}
.mx-toggle svg { width: 14px; height: 14px; }
/* checkbox-backed toggle: a <label class="mx-toggle"> wrapping a real
   checkbox — the input stays in the form data, the label shows the state */
.mx-toggle input[type="checkbox"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.mx-toggle-group {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius);
  background: var(--mx-surface);
}

/* ---------------------------------------------------- 32 · Collapsible */
.mx-collapsible summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--mx-gap-3);
  list-style: none;
  cursor: pointer;
  font-size: var(--mx-text-sm);
  font-weight: 500;
}
.mx-collapsible summary::-webkit-details-marker { display: none; }
.mx-collapsible summary .mx-collapsible__chevron {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--mx-radius-sm);
  color: var(--mx-muted);
  transition: background var(--mx-dur-fast), rotate var(--mx-dur-slow) var(--mx-ease-out);
}
.mx-collapsible summary:hover .mx-collapsible__chevron { background: var(--mx-surface-strong); }
.mx-collapsible[open] .mx-collapsible__chevron { rotate: 180deg; }
.mx-collapsible__content {
  padding-top: 8px;
  animation: mx-acc-in var(--mx-dur-slow) var(--mx-ease-out);
}

/* --------------------------------------------------- 33 · Aspect ratio */
.mx-aspect {
  aspect-ratio: var(--ratio, 16 / 9);
  width: 100%;
  overflow: hidden;
  border-radius: var(--mx-radius-lg);
  border: 1px solid var(--mx-line);
  background: var(--mx-surface-strong);
}
.mx-aspect > img,
.mx-aspect > video,
.mx-aspect > iframe {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border: 0;
}

/* ---------------------------------------------------- 34 · Scroll area */
.mx-scroll {
  overflow: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--mx-line-strong) transparent;
}
.mx-scroll::-webkit-scrollbar { width: 8px; height: 8px; }
.mx-scroll::-webkit-scrollbar-track { background: transparent; }
.mx-scroll::-webkit-scrollbar-thumb {
  background: var(--mx-line-strong);
  border-radius: var(--mx-radius-pill);
  border: 2px solid transparent;
  background-clip: padding-box;
}
.mx-scroll::-webkit-scrollbar-thumb:hover { background-color: var(--mx-muted-2); }

/* Global scrollbar baseline — every scroll container in the app inherits the
   thin, theme-aware scrollbar .mx-scroll defines, no opt-in class needed.
   Firefox via scrollbar-*; WebKit via the pseudo-elements. Custom props
   cascade, so a scoped .mx-<view> that redefines --mx-line-strong themes its
   own scrollbars. Elements that deliberately hide their scrollbar (tab strips,
   drag-scroll tables) override this with a more-specific rule and still win. */
* { scrollbar-width: thin; scrollbar-color: var(--mx-line-strong, rgba(100,116,139,.35)) transparent; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--mx-line-strong, rgba(100,116,139,.35));
  border-radius: var(--mx-radius-pill, 999px);
  border: 2px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background-color: var(--mx-muted-2, rgba(100,116,139,.55)); }
::-webkit-scrollbar-corner { background: transparent; }

/* Hidden-scrollbar utility (shadcn's `scrollbar-none`). The element still
   scrolls — wheel, drag, keyboard, scrollIntoView all work — the bar just
   isn't painted and takes no gutter, so content doesn't shift when it
   appears. Use on chrome surfaces where a visible bar reads as noise:
   sidebar nav, tab strips, segmented rails. Not for content regions, where
   the bar is a needed affordance that more content exists. */
.mx-scroll-none { scrollbar-width: none; -ms-overflow-style: none; }
.mx-scroll-none::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* -------------------------------------------------------- 35 · Popover */
.mx-popover { position: relative; display: inline-block; }
.mx-popover__panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 900;
  width: 280px;
  padding: 14px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  box-shadow: var(--mx-shadow-md);
  transform-origin: top left;
  font-size: var(--mx-text-sm);
}
.mx-popover__panel--end { left: auto; right: 0; transform-origin: top right; }
/* Date-picker panel is just a positioning shell — the inner .mx-calendar is the
   card. Strip the panel's own card so it doesn't render a card-inside-a-card. */
.mx-dtp__field {
  position: relative;
  display: grid;
  align-items: center;
  width: 100%;
  min-width: 0;
}
.mx-dtp__field > .mx-dtp__trigger {
  grid-area: 1 / 1;
  width: 100%;
  min-width: 0;
  justify-content: flex-start;
  font-weight: 400;
  padding-right: 42px;
}
.mx-dtp__trigger > span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mx-dtp__clear {
  grid-area: 1 / 1;
  justify-self: end;
  align-self: center;
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-right: 8px;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  color: var(--mx-muted);
  background: var(--mx-surface-strong);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--mx-dur), color var(--mx-dur);
}
.mx-dtp__clear:hover { color: var(--mx-ink); background: var(--mx-line-strong); }
.mx-dtp__clear svg { width: 12px; height: 12px; }
.mx-dtp__panel {
  width: auto;
  padding: 0;
  background: none;
  border: none;
  box-shadow: none;
}
.mx-popover__title { margin: 0 0 2px; font-weight: 600; letter-spacing: -0.006em; }
.mx-popover__desc  { margin: 0 0 10px; color: var(--mx-muted); font-size: var(--mx-text-xs); }

/* ------------------------------------------------------ 36 · Hover card */
.mx-hc { position: relative; display: inline-block; }
.mx-hc__card {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  translate: -50% 4px;
  z-index: 900;
  width: 300px;
  padding: 14px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  box-shadow: var(--mx-shadow-md);
  font-size: var(--mx-text-sm);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--mx-dur) var(--mx-ease-out),
    translate var(--mx-dur) var(--mx-ease-out), visibility 0s linear var(--mx-dur);
}
.mx-hc:hover .mx-hc__card,
.mx-hc:focus-within .mx-hc__card {
  opacity: 1;
  visibility: visible;
  translate: -50% 0;
  transition-delay: 0.35s, 0.35s, 0.35s;
}

/* ---------------------------------------------------- 37 · Alert dialog */
.mx-modal--alert { text-align: center; max-width: 440px; }
.mx-modal--alert .mx-modal__header { padding: 32px 34px 6px; border-bottom: 0; }
.mx-modal--alert .mx-modal__footer { justify-content: center; gap: 10px; padding: 22px 34px 30px; border-top: 0; background: transparent; }
.mx-modal--alert .mx-modal__badge-icon { width: 52px; height: 52px; font-size: 22px; margin-bottom: 16px; }
.mx-modal--alert .mx-modal__title { font-size: var(--mx-text-xl); }
.mx-modal--alert .mx-modal__desc { margin-top: 8px; }
.mx-modal--alert .mx-btn { min-width: 116px; }
.mx-modal--alert .mx-modal__header { padding-top: 24px; }
.mx-modal--alert .mx-modal__footer { justify-content: center; }
.mx-modal__badge-icon {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  margin: 0 auto 12px;
  border-radius: 50%;
  font-size: 17px;
  background: var(--mx-red-tint);
  color: var(--mx-red-fg);
}

/* -------------------------------------------- 37b · Dialog variants */
/* close button (top-right corner) */
.mx-modal__close {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: var(--mx-radius);
  background: transparent;
  color: var(--mx-muted);
  cursor: pointer;
  transition: background var(--mx-dur), color var(--mx-dur);
}
.mx-modal__close:hover { background: var(--mx-surface-strong); color: var(--mx-ink); }
.mx-modal__close:focus-visible {
  outline: none;
  box-shadow: var(--mx-ring);
}
.mx-modal__close svg { width: 16px; height: 16px; }
/* keep the title clear of the corner button */
.mx-modal__header--closable { padding-right: 52px; }
/* custom variant — a labelled outline pill instead of the bare icon */
.mx-modal__close--custom {
  width: auto;
  height: 28px;
  gap: 5px;
  padding: 0 10px;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  color: var(--mx-ink-soft);
  border: 1px solid var(--mx-line-strong);
  background: var(--mx-surface);
  box-shadow: var(--mx-shadow-xs);
}
.mx-modal__close--custom:hover { background: var(--mx-surface-soft); color: var(--mx-ink); }
.mx-modal__close--custom svg { width: 13px; height: 13px; }

/* scrollable content — fixed header + footer, body scrolls */
.mx-modal--scroll {
  display: flex;
  flex-direction: column;
  max-height: min(560px, calc(100dvh - 48px));
}
.mx-modal--scroll .mx-modal__header,
.mx-modal--scroll .mx-modal__footer { flex-shrink: 0; }
.mx-modal--scroll .mx-modal__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* delineate the scroll boundary under the header */
.mx-modal--scroll .mx-modal__header { padding-bottom: 16px; border-bottom: 1px solid var(--mx-line); }
/* Server-rendered dialogs wrap body+footer (or __scroll+footer) in a <form>;
   keep the flex chain alive through it so the body still scrolls and the
   footer stays pinned instead of being clipped by the modal's overflow. */
.mx-modal--scroll > form,
.mx-modal--sticky > form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

/* sticky footer — header scrolls with content, footer stays pinned */
.mx-modal--sticky {
  display: flex;
  flex-direction: column;
  max-height: min(560px, calc(100dvh - 48px));
}
.mx-modal--sticky .mx-modal__scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.mx-modal--sticky .mx-modal__footer { flex-shrink: 0; }

/* ----------------------------------------------------- 38 · Input group */
.mx-input-group {
  display: flex;
  align-items: stretch;
  width: 100%;
}
.mx-input-group > .mx-input {
  border-radius: 0;
  box-shadow: none;
  position: relative;
}
.mx-input-group > .mx-input:focus { z-index: 1; }
.mx-input-group > :first-child { border-radius: var(--mx-radius) 0 0 var(--mx-radius); }
.mx-input-group > :last-child  { border-radius: 0 var(--mx-radius) var(--mx-radius) 0; }
.mx-input-group > * + * { margin-left: -1px; }
.mx-input-group__addon {
  display: inline-flex;
  align-items: center;
  padding: 0 11px;
  font-size: var(--mx-text-sm);
  color: var(--mx-muted);
  background: var(--mx-surface-soft);
  border: 1px solid var(--mx-line-strong);
  white-space: nowrap;
}
.mx-input-group > .mx-btn { border-radius: 0; }
.mx-input-group > .mx-btn:last-child { border-radius: 0 var(--mx-radius) var(--mx-radius) 0; }

/* ------------------------------------------------------ 39 · Input OTP */
.mx-otp { display: inline-flex; gap: 8px; }
.mx-otp__slot {
  width: 38px;
  height: 44px;
  text-align: center;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--mx-ink);
  background: var(--mx-surface);
  border: 1px solid var(--mx-line-strong);
  border-radius: var(--mx-radius);
  box-shadow: var(--mx-shadow-xs);
  transition: border-color var(--mx-dur), box-shadow var(--mx-dur);
}
.mx-otp__slot:focus {
  outline: none;
  border-color: var(--mx-brand);
  box-shadow: var(--mx-ring);
}
.mx-otp__sep { align-self: center; color: var(--mx-muted-2); }

/* -------------------------------------------------------- 40 · Combobox */
.mx-combobox { position: relative; }
.mx-combobox__list {
  position: absolute;
  top: calc(100% + 5px);
  left: 0;
  right: 0;
  z-index: 900;
  max-height: 220px;
  overflow: auto;
  padding: 4px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  box-shadow: var(--mx-shadow-md);
}
.mx-combobox__opt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 10px;
  font-size: var(--mx-text-sm);
  color: var(--mx-ink-soft);
  border-radius: var(--mx-radius-sm);
  cursor: pointer;
}
.mx-combobox__opt.is-active { background: var(--mx-surface-strong); color: var(--mx-ink); }
.mx-combobox__opt .check { color: var(--mx-brand-fg); font-weight: 700; }
.mx-combobox__empty {
  padding: 14px 10px;
  text-align: center;
  font-size: var(--mx-text-sm);
  color: var(--mx-muted-2);
}

/* group heading inside the list (Groups variant) */
.mx-combobox__group {
  padding: 8px 10px 4px;
  font-size: var(--mx-text-xs);
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--mx-muted-2);
}
.mx-combobox__group + .mx-combobox__opt { margin-top: 0; }
.mx-combobox__list > .mx-combobox__group:not(:first-child) {
  margin-top: 4px;
  border-top: 1px solid var(--mx-line);
  padding-top: 8px;
}

/* rich rows (Custom Items variant) */
.mx-combobox__opt.is-rich { align-items: flex-start; padding: 8px 10px; }
.mx-combobox__opt-media {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: var(--mx-radius-sm);
  background: var(--mx-surface-strong);
  color: var(--mx-ink-soft);
  font-size: var(--mx-text-xs);
  font-weight: 600;
}
.mx-combobox__opt-body { flex: 1; min-width: 0; }
.mx-combobox__opt-body b { display: block; font-weight: 600; color: var(--mx-ink); }
.mx-combobox__opt-body span { font-size: var(--mx-text-xs); color: var(--mx-muted); }
.mx-combobox__opt.is-disabled {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

/* multi-select control — chips live INSIDE the field (Multiple variant) */
.mx-combobox__control {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
  min-height: var(--mx-h-md);
  padding: 4px 8px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line-strong);
  border-radius: var(--mx-radius);
  box-shadow: var(--mx-shadow-xs);
  cursor: text;
  transition: border-color var(--mx-dur), box-shadow var(--mx-dur);
}
.mx-combobox__control:hover { border-color: var(--mx-muted-2); }
.mx-combobox__control:focus-within {
  border-color: var(--mx-brand);
  box-shadow: var(--mx-ring);
}
/* the inline text field is borderless — the control draws the frame */
.mx-combobox__control > .mx-input {
  flex: 1 1 80px;
  width: auto;
  min-width: 60px;
  height: 26px;
  padding: 0 2px;
  background: transparent;
  border: 0;
  box-shadow: none;
}
.mx-combobox__control > .mx-input:hover,
.mx-combobox__control > .mx-input:focus {
  border: 0;
  box-shadow: none;
  outline: none;
}
.mx-combobox__tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 24px;
  padding: 0 4px 0 9px;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  color: var(--mx-brand-fg);
  background: var(--mx-brand-tint);
  border-radius: var(--mx-radius-sm);
}
.mx-combobox__tag button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: inherit;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--mx-dur);
}
.mx-combobox__tag button:hover { background: rgba(105, 108, 255, 0.22); }

/* clear button (Clear Button variant) */
.mx-combobox__field { position: relative; }
.mx-combobox__field > .mx-input { padding-right: 32px; }
.mx-combobox__clear {
  position: absolute;
  top: 50%;
  right: 8px;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--mx-surface-strong);
  color: var(--mx-muted);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--mx-dur), color var(--mx-dur);
}
.mx-combobox__clear:hover { background: var(--mx-line-strong); color: var(--mx-ink); }

/* button trigger (Popup variant) */
.mx-combobox__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  height: var(--mx-h-md);
  padding: 0 11px;
  font: inherit;
  font-size: var(--mx-text-sm);
  color: var(--mx-ink);
  text-align: left;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line-strong);
  border-radius: var(--mx-radius);
  box-shadow: var(--mx-shadow-xs);
  cursor: pointer;
  transition: border-color var(--mx-dur), box-shadow var(--mx-dur);
}
.mx-combobox__trigger:hover { border-color: var(--mx-muted-2); }
.mx-combobox__trigger[aria-expanded="true"] {
  border-color: var(--mx-brand);
  box-shadow: var(--mx-ring);
}
.mx-combobox__trigger.is-placeholder { color: var(--mx-muted-2); }
.mx-combobox__trigger svg { width: 15px; height: 15px; color: var(--mx-muted-2); flex: 0 0 auto; }
/* search box pinned at top of the popup panel */
.mx-combobox__search {
  padding: 4px 4px 6px;
  margin-bottom: 2px;
  border-bottom: 1px solid var(--mx-line);
}
.mx-combobox__search .mx-input { height: var(--mx-h-sm); }

/* --------------------------------------------------------- 41 · Command */
.mx-command {
  width: 100%;
  max-width: 540px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  box-shadow: var(--mx-shadow-lg);
  overflow: hidden;
}
.mx-command__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  border-bottom: 1px solid var(--mx-line);
}
.mx-command__head svg { width: 15px; height: 15px; color: var(--mx-muted-2); flex: 0 0 auto; }
.mx-command__input {
  flex: 1;
  height: 46px;
  border: none;
  background: none;
  font: inherit;
  font-size: var(--mx-text-base);
  color: var(--mx-ink);
}
.mx-command__input:focus { outline: none; }
.mx-command__input::placeholder { color: var(--mx-muted-2); }
.mx-command__list {
  max-height: 300px;
  overflow: auto;
  padding: 6px;
}
.mx-command__group-label {
  padding: 8px 10px 4px;
  font-size: 11px;
  font-weight: 500;
  color: var(--mx-muted-2);
}
.mx-command__item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 10px;
  font: inherit;
  font-size: var(--mx-text-sm);
  color: var(--mx-ink-soft);
  background: none;
  border: none;
  border-radius: var(--mx-radius-sm);
  text-align: left;
  cursor: pointer;
}
.mx-command__item.is-active,
.mx-command__item:hover { background: var(--mx-surface-strong); color: var(--mx-ink); }
.mx-command__item .mx-kbd { margin-left: auto; }
.mx-command__empty {
  padding: 28px 10px;
  text-align: center;
  font-size: var(--mx-text-sm);
  color: var(--mx-muted-2);
}

/* ---------------------------------------------------- 42 · Context menu */
.mx-context-zone {
  display: grid;
  place-items: center;
  min-height: 120px;
  padding: 20px;
  border: 1px dashed var(--mx-line-strong);
  border-radius: var(--mx-radius-lg);
  font-size: var(--mx-text-sm);
  color: var(--mx-muted);
  user-select: none;
}
.mx-context-menu {
  position: fixed;
  z-index: 1050;
  min-width: 180px;
  padding: 4px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  box-shadow: var(--mx-shadow-md);
}

/* --------------------------------------------------------- 43 · Menubar */
.mx-menubar {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius);
  box-shadow: var(--mx-shadow-xs);
}
.mx-menubar .mx-dropdown > .mx-menubar__trigger {
  display: inline-flex;
  align-items: center;
  height: calc(var(--mx-h-sm) - 6px);
  padding: 0 10px;
  font: inherit;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  color: var(--mx-ink-soft);
  background: none;
  border: none;
  border-radius: var(--mx-radius-sm);
  cursor: pointer;
}
.mx-menubar .mx-dropdown > .mx-menubar__trigger:hover,
.mx-menubar .mx-dropdown > .mx-menubar__trigger[aria-expanded="true"] {
  background: var(--mx-surface-strong);
  color: var(--mx-ink);
}

/* -------------------------------------------------------- 44 · Calendar */
.mx-calendar {
  display: inline-block;
  padding: 12px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  box-shadow: var(--mx-shadow-xs);
}
.mx-calendar__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.mx-calendar__title {
  font-size: var(--mx-text-sm);
  font-weight: 600;
  letter-spacing: -0.006em;
}
.mx-calendar__nav {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  font: inherit;
  color: var(--mx-muted);
  background: none;
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-sm);
  cursor: pointer;
  transition: background var(--mx-dur-fast), color var(--mx-dur-fast);
}
.mx-calendar__nav:hover { background: var(--mx-surface-strong); color: var(--mx-ink); }
.mx-calendar__grid {
  display: grid;
  grid-template-columns: repeat(7, 32px);
  gap: 2px;
}
.mx-calendar__dow {
  height: 26px;
  display: grid;
  place-items: center;
  font-size: 10.5px;
  font-weight: 500;
  color: var(--mx-muted-2);
}
.mx-calendar__day {
  height: 32px;
  display: grid;
  place-items: center;
  font: inherit;
  font-size: var(--mx-text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--mx-ink-soft);
  background: none;
  border: none;
  border-radius: var(--mx-radius-sm);
  cursor: pointer;
  transition: background var(--mx-dur-fast), color var(--mx-dur-fast);
}
.mx-calendar__day:hover { background: var(--mx-surface-strong); }
.mx-calendar__day.is-out { color: var(--mx-muted-2); }
.mx-calendar__day.is-disabled {
  color: var(--mx-muted-2);
  opacity: 0.45;
  cursor: not-allowed;
  background: transparent;
}
.mx-calendar__day.is-today { box-shadow: inset 0 0 0 1px var(--mx-line-strong); font-weight: 600; }
.mx-calendar__day.is-selected {
  background: var(--mx-brand);
  color: var(--mx-on-brand);
  font-weight: 600;
}

/* range selection — cells connect horizontally (no column gap) */
.mx-calendar--range .mx-calendar__grid { column-gap: 0; }
.mx-calendar--range .mx-calendar__day { border-radius: 0; }
.mx-calendar__day.is-in-range {
  background: var(--mx-brand-tint);
  color: var(--mx-ink-soft);
}
.mx-calendar__day.is-range-start,
.mx-calendar__day.is-range-end {
  background: var(--mx-brand);
  color: var(--mx-on-brand);
  font-weight: 600;
}
.mx-calendar__day.is-range-start { border-radius: var(--mx-radius-sm) 0 0 var(--mx-radius-sm); }
.mx-calendar__day.is-range-end { border-radius: 0 var(--mx-radius-sm) var(--mx-radius-sm) 0; }
.mx-calendar__day.is-range-start.is-range-end { border-radius: var(--mx-radius-sm); }

/* Floating date-picker calendars (inside a popover / dtp panel) must read as
   clearly ELEVATED — the picker templates set an inline box-shadow:var(--mx-shadow-md)
   which is too soft to separate a white calendar card from a white card/modal
   behind it. Promote every floating calendar to the elevation-lg shadow (same
   family the dropdowns use); `!important` beats the inline value. Inline calendars
   (Calendar section, no popover ancestor) are untouched — they keep shadow-xs. */
.mx-popover__panel .mx-calendar,
.mx-dtp__panel .mx-calendar {
  box-shadow: var(--mx-shadow-lg) !important;
}

/* Two-month range calendar (shadcn-style): one shared header (prev far-left,
   next far-right, a centered caption over each month) above two grids side by
   side. Collapses to a single month under 560px so the panel never overflows a
   phone. Additive modifier — the single-month .mx-calendar--range is untouched. */
.mx-calendar--duo { display: inline-block; }
.mx-calendar--duo .mx-calendar__duohead { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.mx-calendar--duo .mx-calendar__duotitles { flex: 1; display: flex; }
.mx-calendar--duo .mx-calendar__duotitle { flex: 1; text-align: center; font-size: var(--mx-text-sm); font-weight: 600; letter-spacing: -0.006em; }
.mx-calendar--duo .mx-calendar__months { display: flex; gap: 20px; align-items: flex-start; }
/* Each month shows only its own days — hide the spill-over from the adjacent
   month (shadcn does the same in range mode) so boundary days aren't painted
   with the range in both grids. `visibility` keeps the 6-row height so the two
   months stay aligned. */
.mx-calendar--duo .mx-calendar__day.is-out { visibility: hidden; }
@media (max-width: 560px) {
  .mx-calendar--duo .mx-calendar__month--2,
  .mx-calendar--duo .mx-calendar__duotitle--2 { display: none; }
}

/* caption dropdowns (Date of Birth variant) */
.mx-calendar__caption { display: flex; gap: 6px; flex: 1; }
.mx-calendar__select {
  appearance: none;
  height: 28px;
  padding: 0 24px 0 8px;
  font: inherit;
  font-size: var(--mx-text-xs);
  font-weight: 600;
  color: var(--mx-ink);
  background-color: var(--mx-surface);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 6px center;
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-sm);
  cursor: pointer;
  transition: border-color var(--mx-dur-fast);
}
.mx-calendar__select:hover { border-color: var(--mx-muted-2); }
.mx-calendar__select:focus { outline: none; border-color: var(--mx-brand); box-shadow: var(--mx-ring); }
.mx-calendar__caption .mx-calendar__select:first-child { flex: 1; }
.mx-calendar__caption .mx-caldd:first-child { flex: 1; }
.mx-calendar__caption .mx-caldd:first-child .mx-calendar__select { width: 100%; }

/* caption dropdown (.mx-caldd) — custom month/year picker replacing the
   native <select>, whose year list renders as a giant OS popup */
.mx-caldd { position: relative; }
.mx-caldd > .mx-calendar__select { text-align: left; }
.mx-caldd__panel {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 40;
  min-width: 100%;
  max-height: 232px;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  padding: 4px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-sm);
  box-shadow: var(--mx-shadow-md);
}
.mx-caldd__item {
  appearance: none;
  flex: 0 0 auto;
  padding: 5px 10px;
  font: inherit;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  color: var(--mx-ink-soft);
  background: none;
  border: none;
  border-radius: var(--mx-radius-sm);
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}
.mx-caldd__item:hover { background: var(--mx-surface-strong); color: var(--mx-ink); }
.mx-caldd__item.is-selected { background: var(--mx-brand); color: var(--mx-on-brand); font-weight: 600; }

/* footer strip inside a date popover (Time Picker variant) */
.mx-calendar__footer {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--mx-line);
}
.mx-calendar__footer .mx-label { margin: 0; white-space: nowrap; }
.mx-calendar__footer .mx-input { height: 30px; }

/* ---- Time picker (mxTimePicker): scrollable Hour / Minute / AM·PM columns */
.mx-timepicker__panel { width: auto; padding: 0; background: none; border: none; box-shadow: none; }
.mx-timepicker__trigger { justify-content: flex-start; font-weight: 400; }
.mx-timepicker {
  display: flex;
  gap: 4px;
  padding: 6px;
  background: var(--mx-surface);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  box-shadow: var(--mx-shadow-md);
}
.mx-timepicker__col {
  display: flex;
  flex-direction: column;
  gap: 2px;
  height: 216px;
  overflow-y: auto;
  scrollbar-width: thin;
  padding-right: 2px;
  scroll-behavior: smooth;
}
.mx-timepicker__col::-webkit-scrollbar { width: 6px; }
.mx-timepicker__col::-webkit-scrollbar-thumb { background: var(--mx-line); border-radius: 3px; }
.mx-timepicker__item {
  flex: 0 0 auto;
  min-width: 46px;
  padding: 6px 10px;
  border: 0;
  border-radius: var(--mx-radius-sm);
  color: var(--mx-ink-soft);
  background: transparent;
  font: inherit;
  font-size: var(--mx-text-sm);
  font-variant-numeric: tabular-nums;
  text-align: center;
  cursor: pointer;
}
.mx-timepicker__item:hover { background: var(--mx-surface-strong); }
.mx-timepicker__item.is-active { color: var(--mx-on-brand); background: var(--mx-brand); }

/* -------------------------------------------------------- 45 · Carousel */
.mx-carousel { position: relative; }
.mx-carousel__viewport {
  overflow: hidden;
  border-radius: var(--mx-radius-lg);
  border: 1px solid var(--mx-line);
}
.mx-carousel__track {
  display: flex;
  transition: transform 0.4s var(--mx-ease-out);
}
.mx-carousel__slide {
  flex: 0 0 100%;
  min-width: 0;
}
.mx-carousel__btn {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  z-index: 2;
}
.mx-carousel__btn--prev { left: 10px; }
.mx-carousel__btn--next { right: 10px; }
.mx-carousel__dots {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 10px;
}
.mx-carousel__dot {
  width: 6px;
  height: 6px;
  padding: 0;
  border: none;
  border-radius: var(--mx-radius-pill);
  background: var(--mx-line-strong);
  cursor: pointer;
  transition: background var(--mx-dur), width var(--mx-dur) var(--mx-ease-out);
}
.mx-carousel__dot.is-active { background: var(--mx-brand); width: 16px; }

/* ----------------------------------------- 46 · Data table (sortable th) */
.mx-th-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font: inherit;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  color: var(--mx-muted);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: color var(--mx-dur-fast);
}
.mx-th-btn:hover { color: var(--mx-ink); }
.mx-th-btn .dir { font-size: 10px; width: 10px; }

/* ------------------------------------------------------- 47 · Resizable */
.mx-resizable {
  display: flex;
  height: 150px;
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  background: var(--mx-surface);
  overflow: hidden;
}
.mx-resizable__pane {
  display: grid;
  place-items: center;
  font-size: var(--mx-text-sm);
  color: var(--mx-muted);
  min-width: 0;
}
.mx-resizable__handle {
  flex: 0 0 5px;
  cursor: col-resize;
  background: var(--mx-line);
  transition: background var(--mx-dur-fast);
  touch-action: none;
}
.mx-resizable__handle:hover,
.mx-resizable__handle.is-dragging { background: var(--mx-brand); }

/* ----------------------------------------------------------- 48 · Chart */
.mx-bars {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  height: 120px;
  width: 100%;
}
.mx-bars__col {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  height: 100%;
  gap: 6px;
  min-width: 0;
}
.mx-bars__bar {
  border-radius: 5px 5px 2px 2px;
  background: var(--mx-brand);
  opacity: 0.85;
  transition: opacity var(--mx-dur-fast);
  min-height: 4px;
}
.mx-bars__col:hover .mx-bars__bar { opacity: 1; }
.mx-bars__bar--muted { background: var(--mx-surface-strong); opacity: 1; }
.mx-bars__label {
  text-align: center;
  font-size: 10.5px;
  color: var(--mx-muted-2);
}

/* --------------------------------------------------------- 49 · Sidebar */
.mx-sidebar {
  display: flex;
  flex-direction: column;
  width: 232px;
  background: var(--mx-surface-soft);
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius-lg);
  overflow: hidden;
}
.mx-sidebar__brand {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 14px;
  font-size: var(--mx-text-sm);
  font-weight: 650;
  letter-spacing: -0.01em;
  border-bottom: 1px solid var(--mx-line);
}
.mx-sidebar__logo {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background: linear-gradient(135deg, var(--mx-brand-bright), var(--mx-brand-deep));
  color: #fff;
  font-size: 12px;
  font-weight: 700;
}
/* Brand artwork. The consumer supplies the images as URLs on `.mx-sidebar__brand`:
   --mx-brand-logo / --mx-brand-logo-dark = full logotipo, shown when expanded;
   --mx-brand-mark / --mx-brand-mark-dark = square mark, shown in the collapsed rail.
   Feed it art with NO transparent margin (crop it) — the box edge must be the art edge
   or the brand won't line up with the nav's text column. Width = art ratio x height. */
.mx-sidebar__brand-logo {
  display: block;
  width: 96px;
  height: 30px;
  flex: 0 0 auto;
  background: var(--mx-brand-logo) left center / contain no-repeat;
  transition: width var(--mx-dur-slow) var(--mx-ease-out);
}
:root[data-theme="dark"] .mx-sidebar__brand-logo { background-image: var(--mx-brand-logo-dark); }
.mx-sidebar.is-collapsed .mx-sidebar__brand-logo {
  width: 33px;
  height: 33px;
  background-image: var(--mx-brand-mark);
}
:root[data-theme="dark"] .mx-sidebar.is-collapsed .mx-sidebar__brand-logo {
  background-image: var(--mx-brand-mark-dark);
}
/* Scrolls, but the bar is never painted (see .mx-scroll-none) — matches the
   shadcn sidebar, where the nav overflows silently instead of growing a rail. */
.mx-sidebar__nav { flex: 1; padding: 10px 8px; overflow-y: auto; scrollbar-width: none; -ms-overflow-style: none; }
.mx-sidebar__nav::-webkit-scrollbar { width: 0; height: 0; display: none; }
/* Section header doubles as a collapse toggle. Kept deliberately quiet:
   the chevron is invisible until you hover the header, so an expanded rail
   looks identical to a plain label. Sections default to open (set in markup).
   Collapse is a dependency-free grid-rows transition (1fr -> 0fr). */
.mx-sidebar__section { display: flex; flex-direction: column; }
.mx-sidebar__group {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 12px 10px 4px;
  font: inherit;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--mx-muted-2);
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  user-select: none;
}
.mx-sidebar__group-chev {
  width: 13px; height: 13px;
  flex: 0 0 auto;
  opacity: 0;
  transition: opacity var(--mx-dur-fast), transform var(--mx-dur-fast) var(--mx-ease-out);
}
.mx-sidebar__group:hover .mx-sidebar__group-chev,
.mx-sidebar__group:focus-visible .mx-sidebar__group-chev { opacity: 0.55; }
.mx-sidebar__group-chev.is-collapsed { transform: rotate(-90deg); opacity: 0.4; }
.mx-sidebar__group:hover .mx-sidebar__group-chev.is-collapsed { opacity: 0.7; }
.mx-sidebar__items {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows var(--mx-dur-slow) var(--mx-ease-out);
}
.mx-sidebar__items.is-collapsed { grid-template-rows: 0fr; }
.mx-sidebar__items-inner { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
/* In the 64px icon rail the headers are hidden — never let a collapsed
   section hide its icons; force every section open. */
.mx-sidebar.is-collapsed .mx-sidebar__items { grid-template-rows: 1fr; }
.mx-sidebar__item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 10px;
  font: inherit;
  font-size: var(--mx-text-base);
  color: var(--mx-muted);
  background: none;
  border: none;
  border-radius: var(--mx-radius-sm);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--mx-dur-fast), color var(--mx-dur-fast);
}
.mx-sidebar__item:hover { background: var(--mx-surface-strong); color: var(--mx-ink); }
.mx-sidebar__item.is-active {
  background: var(--mx-brand-tint);
  color: var(--mx-brand-fg);
  font-weight: 500;
}
.mx-sidebar__item svg { width: 15px; height: 15px; flex: 0 0 auto; }
.mx-sidebar__item .mx-badge { margin-left: auto; }
/* Splits a section into visual sub-groups (e.g. Operations). Modern sidebars
   (Linear, Vercel, shadcn) group with whitespace, not a rule — so this is a
   transparent spacer, not a line. Bump the height to widen the breathing room. */
.mx-sidebar__sep {
  height: 7px;
}
.mx-sidebar__footer {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 14px;
  border-top: 1px solid var(--mx-line);
  font-size: var(--mx-text-xs);
}
.mx-sidebar__footer b { display: block; font-size: var(--mx-text-sm); font-weight: 550; }
.mx-sidebar__footer span { color: var(--mx-muted); }

/* Collapsible → icon rail (shadcn-style). Add `x-data="mxSidebar()"` and
   `x-bind:class="collapsed && 'is-collapsed'"`; wrap nav text in
   `.mx-sidebar__label` and mirror it in `data-label` for the hover tooltip. */
.mx-sidebar {
  transition: width var(--mx-dur-slow) var(--mx-ease-out);
}
.mx-sidebar__brand-text,
.mx-sidebar__label {
  white-space: nowrap;
  overflow: hidden;
}
.mx-sidebar__brand { position: relative; }
.mx-sidebar__toggle {
  margin-left: auto;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex: 0 0 auto;
  color: var(--mx-muted);
  background: none;
  border: none;
  border-radius: var(--mx-radius-sm);
  cursor: pointer;
  transition: background var(--mx-dur-fast), color var(--mx-dur-fast);
}
.mx-sidebar__toggle:hover { background: var(--mx-surface-strong); color: var(--mx-ink); }
.mx-sidebar__toggle svg {
  width: 16px;
  height: 16px;
  transition: transform var(--mx-dur) var(--mx-ease-out);
}

/* Collapsed state */
.mx-sidebar.is-collapsed {
  width: 64px;
  overflow: visible; /* let the hover tooltips escape the rail */
}
.mx-sidebar.is-collapsed .mx-sidebar__nav { overflow: visible; }
.mx-sidebar.is-collapsed .mx-sidebar__brand { justify-content: center; padding-inline: 0; gap: 0; }
.mx-sidebar.is-collapsed .mx-sidebar__item { justify-content: center; padding-inline: 0; }
.mx-sidebar.is-collapsed .mx-sidebar__footer { justify-content: center; padding-inline: 0; }
.mx-sidebar.is-collapsed .mx-sidebar__brand-text,
.mx-sidebar.is-collapsed .mx-sidebar__label,
.mx-sidebar.is-collapsed .mx-sidebar__group,
.mx-sidebar.is-collapsed .mx-sidebar__user,
.mx-sidebar.is-collapsed .mx-sidebar__item .mx-badge {
  display: none;
}
.mx-sidebar.is-collapsed .mx-sidebar__toggle { margin: 0; }
.mx-sidebar.is-collapsed .mx-sidebar__toggle svg { transform: rotate(180deg); }

/* Hover tooltip — only rendered while collapsed, reads `data-label` */
.mx-sidebar__item,
.mx-sidebar__toggle { position: relative; }
.mx-sidebar.is-collapsed [data-label]::after {
  content: attr(data-label);
  position: absolute;
  left: calc(100% + 10px);
  top: 50%;
  translate: -3px 0;
  transform: translateY(-50%);
  padding: 5px 9px;
  font-size: var(--mx-text-xs);
  font-weight: 500;
  letter-spacing: -0.003em;
  line-height: 1.35;
  white-space: nowrap;
  color: var(--mx-bg);
  background: var(--mx-ink);
  border-radius: var(--mx-radius-sm);
  box-shadow: var(--mx-shadow-md);
  opacity: 0;
  pointer-events: none;
  z-index: 60;
  transition: opacity var(--mx-dur-fast), translate var(--mx-dur-fast);
}
.mx-sidebar.is-collapsed [data-label]:hover::after,
.mx-sidebar.is-collapsed [data-label]:focus-visible::after { opacity: 1; translate: 0 0; }
@media (prefers-reduced-motion: reduce) {
  .mx-sidebar,
  .mx-sidebar__toggle svg,
  .mx-sidebar [data-label]::after { transition: none; }
}

/* ------------------------------------------------- 44 · Eyebrow (section label)
   Tiny uppercase label for a section header inside cards/popovers/panels. */
.mx-eyebrow {
  font-size: var(--mx-text-xs);
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--mx-muted-2);
}
.mx-eyebrow--gap { margin-top: var(--mx-gap-3); }

/* ------------------------------------------------- 45 · List (people / rows)
   Hairline-separated rows: leading avatar + main (title/sub) + trailing meta.
   Reusable for detail panels, filter lists (clients/employees), etc. */
.mx-list { display: flex; flex-direction: column; }
.mx-list__item {
  display: flex;
  align-items: center;
  gap: var(--mx-gap-2);
  padding: 8px 0;
  border-top: 1px solid var(--mx-line);
}
.mx-list__item:first-child { border-top: 0; }
.mx-list__main { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.mx-list__title { font-size: var(--mx-text-sm); font-weight: 500; color: var(--mx-ink); line-height: 1.25; }
.mx-list__sub { font-size: var(--mx-text-xs); color: var(--mx-muted); line-height: 1.3; }
.mx-list__trailing { margin-left: auto; }

/* ------------------------------------------------- 46 · Button · success
   Positive/confirm action (approve, publish). Pairs with .mx-btn--danger. */
.mx-btn--success {
  --_bg: var(--mx-green);
  --_fg: #ffffff;
  --_sh: inset 0 1px 0 rgba(255, 255, 255, 0.14), var(--mx-shadow-xs);
}
.mx-btn--success:hover { --_bg: var(--mx-green-fg); }


/* ── Page header (canonical title + subtitle, used across all views) ── */
.mx-pagehead { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 20px; }
.mx-pagehead__title { margin: 0; color: var(--mx-ink); font-size: var(--mx-text-xl); font-weight: 650; line-height: 1.2; }
.mx-pagehead__sub { margin: 4px 0 0; color: var(--mx-muted); font-size: var(--mx-text-sm); }
.mx-pagehead__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

.mx-segmented__item svg { width: 16px; height: 16px; flex: 0 0 auto; }
.mx-segmented__item svg + span, .mx-segmented__item span + svg { margin-left: 6px; }


/* ── Stat icon tile (payroll/timesheet KPIs) ── */
.mx-stat--icon { gap: 4px; }
.mx-stat__head { display: flex; align-items: center; gap: 8px; }
.mx-stat--icon .mx-stat__label { font-size: var(--mx-text-xs); }
.mx-stat__icon { width: 26px; height: 26px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.mx-stat__icon svg { width: 15px; height: 15px; }
.mx-stat__icon--brand   { background: var(--mx-brand-tint); color: var(--mx-brand-fg); }
.mx-stat__icon--success { background: var(--mx-green-tint, #e6f7ee); color: var(--mx-green-fg, #16a34a); }
.mx-stat__icon--warning { background: var(--mx-amber-tint, #fdf1dd); color: var(--mx-amber-fg, #d97706); }
.mx-stat__icon--danger  { background: var(--mx-red-tint, #fdecec); color: var(--mx-red-fg, #dc2626); }
.mx-stat__icon--cyan    { background: var(--mx-cyan-tint, #e5f6fb); color: var(--mx-cyan-fg, #0891b2); }
.mx-stat__icon--purple  { background: color-mix(in srgb, #8b5cf6 12%, transparent); color: #7c3aed; }
.mx-stat__icon--muted   { background: var(--mx-surface-strong); color: var(--mx-muted); }

/* ── Checkbox standardization ─────────────────────────────────────────────
   Every checkbox gets the .mx-check look: .mx-checkbox util, legacy .ts-check /
   .mx-check-native, bare .mx-app checkboxes, and transitional .form-check checkboxes.
   Switches (.mx-switch/.mx-toggle/.form-switch) and radios stay untouched. */
.mx-checkbox,
.mx-app .ts-check,
.mx-app .mx-check-native,
.mx-app input[type="checkbox"]:not(.form-check-input):not(.mx-check input):not(.mx-switch input):not(.mx-toggle input):not(.mx-checkbox):not(.ts-check):not(.mx-check-native),
.mx-app .form-check:not(.form-switch) input.form-check-input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  flex: 0 0 auto; width: 16px; height: 16px;
  background: var(--mx-surface); border: 1px solid var(--mx-line-strong);
  border-radius: 5px; box-shadow: var(--mx-shadow-xs); cursor: pointer;
  vertical-align: middle;
  transition: background var(--mx-dur), border-color var(--mx-dur), box-shadow var(--mx-dur);
}
.mx-checkbox:hover,
.mx-app .ts-check:hover,
.mx-app .mx-check-native:hover,
.mx-app input[type="checkbox"]:not(.form-check-input):not(.mx-check input):not(.mx-switch input):not(.mx-toggle input):not(.mx-checkbox):not(.ts-check):not(.mx-check-native):hover,
.mx-app .form-check:not(.form-switch) input.form-check-input[type="checkbox"]:hover { border-color: var(--mx-muted-2); }
.mx-checkbox:focus-visible,
.mx-app .ts-check:focus-visible,
.mx-app .mx-check-native:focus-visible,
.mx-app input[type="checkbox"]:not(.form-check-input):not(.mx-check input):not(.mx-switch input):not(.mx-toggle input):not(.mx-checkbox):not(.ts-check):not(.mx-check-native):focus-visible,
.mx-app .form-check:not(.form-switch) input.form-check-input[type="checkbox"]:focus-visible { outline: none; box-shadow: var(--mx-ring); }
.mx-checkbox:checked,
.mx-app .ts-check:checked,
.mx-app .mx-check-native:checked,
.mx-app input[type="checkbox"]:not(.form-check-input):not(.mx-check input):not(.mx-switch input):not(.mx-toggle input):not(.mx-checkbox):not(.ts-check):not(.mx-check-native):checked,
.mx-app .form-check:not(.form-switch) input.form-check-input[type="checkbox"]:checked {
  background-color: var(--mx-brand); border-color: var(--mx-brand);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-size: 10px; background-position: center; background-repeat: no-repeat;
}
.mx-checkbox:indeterminate,
.mx-app .ts-check:indeterminate,
.mx-app .mx-check-native:indeterminate,
.mx-app input[type="checkbox"]:not(.form-check-input):not(.mx-check input):not(.mx-switch input):not(.mx-toggle input):not(.mx-checkbox):not(.ts-check):not(.mx-check-native):indeterminate,
.mx-app .form-check:not(.form-switch) input.form-check-input[type="checkbox"]:indeterminate {
  background-color: var(--mx-brand); border-color: var(--mx-brand);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E");
  background-size: 10px; background-position: center; background-repeat: no-repeat;
}

/* --------------------------------------------------------- 50 · Upload (mxUpload)
   Drag-and-drop file upload with previews + remove, driving a hidden native
   <input type="file"> (the form-data source of truth). See <c-mx.upload> and the
   mxUpload() Alpine factory. */
.mx-upload { display: flex; flex-direction: column; gap: 10px; }
.mx-upload__zone {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px;
  padding: 22px 16px;
  min-height: 128px;
  text-align: center;
  border: 1.5px dashed var(--mx-line-strong);
  border-radius: var(--mx-radius-lg);
  background: var(--mx-surface-soft);
  color: var(--mx-muted);
  cursor: pointer;
  transition: border-color var(--mx-dur-fast), background var(--mx-dur-fast), color var(--mx-dur-fast);
}
.mx-upload__zone:hover { border-color: var(--mx-muted-2); color: var(--mx-ink-soft); }
.mx-upload__zone:focus-visible { outline: none; border-color: var(--mx-brand); box-shadow: 0 0 0 3px var(--mx-brand-tint); }
.mx-upload__zone.is-dragging {
  border-color: var(--mx-brand); background: var(--mx-surface-brand); color: var(--mx-brand-fg);
}
.mx-upload__icon {
  display: grid; place-items: center;
  width: 40px; height: 40px; border-radius: var(--mx-radius);
  background: var(--mx-surface); border: 1px solid var(--mx-line); color: var(--mx-muted);
}
.mx-upload__icon svg { width: 20px; height: 20px; }
.mx-upload__zone.is-dragging .mx-upload__icon { color: var(--mx-brand-fg); border-color: transparent; background: var(--mx-surface); }
.mx-upload__prompt { font-size: var(--mx-text-sm); font-weight: 500; color: var(--mx-ink); }
.mx-upload__prompt b { color: var(--mx-brand-fg); font-weight: 600; }
.mx-upload__hint { font-size: var(--mx-text-xs); color: var(--mx-muted-2); }
.mx-upload__list { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; list-style: none; }
.mx-upload__file {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--mx-line); border-radius: var(--mx-radius);
  background: var(--mx-surface); font-size: var(--mx-text-sm); min-width: 0;
}
.mx-upload__file-ico { flex: 0 0 auto; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 8px; background: var(--mx-surface-strong); color: var(--mx-muted); }
.mx-upload__file-ico svg { width: 15px; height: 15px; }
.mx-upload__file-main { flex: 1; min-width: 0; }
.mx-upload__file-name { display: block; color: var(--mx-ink); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mx-upload__file-name a { color: inherit; text-decoration: none; }
.mx-upload__file-name a:hover { color: var(--mx-brand-fg); text-decoration: underline; }
.mx-upload__file-meta { font-size: var(--mx-text-xs); color: var(--mx-muted-2); }
.mx-upload__file-remove {
  flex: 0 0 auto; display: grid; place-items: center; width: 26px; height: 26px;
  border: none; background: none; border-radius: 7px; color: var(--mx-muted-2); cursor: pointer;
  transition: background var(--mx-dur-fast), color var(--mx-dur-fast);
}
.mx-upload__file-remove:hover { background: var(--mx-red-tint); color: var(--mx-red-fg); }
.mx-upload__file-remove svg { width: 15px; height: 15px; }
.mx-upload__file--existing .mx-upload__file-ico { background: var(--mx-brand-tint); color: var(--mx-brand-fg); }
.mx-upload[data-disabled] { opacity: .6; pointer-events: none; }

/* --------------------------------------------------------- 26 · Attachment
   A single file/image attachment card — media + metadata + upload state +
   actions. Presentational: pair it with your own upload flow (or <c-mx.upload>).
   Mirrors shadcn's base Attachment: sizes, image (vertical) variant, upload /
   processing / error / done states, and a scrollable AttachmentGroup row. */
.mx-attach {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  min-width: 220px; max-width: 340px;
  border: 1px solid var(--mx-line);
  border-radius: var(--mx-radius);
  background: var(--mx-surface);
  transition: border-color var(--mx-dur-fast), box-shadow var(--mx-dur-fast), background var(--mx-dur-fast);
}
.mx-attach:hover { border-color: var(--mx-line-strong); box-shadow: var(--mx-shadow-xs); }

/* media chip — icon or image thumbnail */
.mx-attach__media {
  flex: 0 0 auto; position: relative; overflow: hidden;
  display: grid; place-items: center;
  width: 36px; height: 36px; border-radius: 8px;
  background: var(--mx-surface-strong); color: var(--mx-muted);
}
.mx-attach__media svg { width: 18px; height: 18px; }
.mx-attach__media img { width: 100%; height: 100%; object-fit: cover; }
.mx-attach__media--brand { background: var(--mx-brand-tint); color: var(--mx-brand-fg); }
.mx-attach__media--red   { background: var(--mx-red-tint);   color: var(--mx-red-fg); }
.mx-attach__media--green { background: var(--mx-green-tint); color: var(--mx-green-fg); }
.mx-attach__media--amber { background: var(--mx-amber-tint); color: var(--mx-amber-fg); }
.mx-attach__media--cyan  { background: var(--mx-cyan-tint);  color: var(--mx-cyan-fg); }

/* content */
.mx-attach__content { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mx-attach__title {
  font-size: var(--mx-text-sm); font-weight: 500; color: var(--mx-ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mx-attach__title a { color: inherit; text-decoration: none; }
.mx-attach__title a:hover { color: var(--mx-brand-fg); text-decoration: underline; }
.mx-attach__desc {
  font-size: var(--mx-text-xs); color: var(--mx-muted-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* actions — icon buttons */
.mx-attach__actions { flex: 0 0 auto; display: flex; align-items: center; gap: 2px; }
.mx-attach__action {
  display: grid; place-items: center; width: 26px; height: 26px;
  border: none; background: none; border-radius: 7px;
  color: var(--mx-muted-2); cursor: pointer;
  transition: background var(--mx-dur-fast), color var(--mx-dur-fast);
}
.mx-attach__action:hover { background: var(--mx-surface-strong); color: var(--mx-ink-soft); }
.mx-attach__action--danger:hover { background: var(--mx-red-tint); color: var(--mx-red-fg); }
.mx-attach__action svg { width: 15px; height: 15px; }

/* progress — thin bar hugging the bottom edge (uploading state) */
.mx-attach__progress {
  position: absolute; left: 1px; right: 1px; bottom: 1px; height: 3px;
  border-radius: 0 0 var(--mx-radius) var(--mx-radius); overflow: hidden;
  background: var(--mx-surface-strong);
}
.mx-attach__progress-bar {
  height: 100%; width: 0; background: var(--mx-brand);
  transition: width var(--mx-dur-slow) var(--mx-ease-out);
}

/* --- states --- */
/* title shimmer during uploading / processing */
.mx-attach.is-uploading .mx-attach__title,
.mx-attach.is-processing .mx-attach__title {
  color: transparent;
  background: linear-gradient(90deg, var(--mx-muted-2) 0%, var(--mx-ink) 50%, var(--mx-muted-2) 100%);
  background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text;
  animation: mx-attach-shimmer 1.6s linear infinite;
}
.mx-attach.is-processing .mx-attach__progress-bar {
  width: 40%; animation: mx-attach-indeterminate 1.2s var(--mx-ease-out) infinite;
}
@keyframes mx-attach-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@keyframes mx-attach-indeterminate {
  0%   { margin-left: -40%; }
  100% { margin-left: 100%; }
}

/* error (destructive) */
.mx-attach.is-error { border-color: color-mix(in srgb, var(--mx-red) 42%, var(--mx-line)); background: var(--mx-red-tint); }
.mx-attach.is-error .mx-attach__media { background: color-mix(in srgb, var(--mx-red-tint) 60%, var(--mx-surface)); color: var(--mx-red-fg); }
.mx-attach.is-error .mx-attach__desc { color: var(--mx-red-fg); }

/* done */
.mx-attach.is-done .mx-attach__media { background: var(--mx-green-tint); color: var(--mx-green-fg); }

/* sizes */
.mx-attach--sm { padding: 6px 8px; min-width: 180px; gap: 8px; }
.mx-attach--sm .mx-attach__media { width: 30px; height: 30px; border-radius: 7px; }
.mx-attach--sm .mx-attach__media svg { width: 15px; height: 15px; }
.mx-attach--xs { padding: 4px 6px 4px 5px; min-width: 0; gap: 7px; }
.mx-attach--xs .mx-attach__media { width: 24px; height: 24px; border-radius: 6px; }
.mx-attach--xs .mx-attach__media svg { width: 13px; height: 13px; }
.mx-attach--xs .mx-attach__desc { display: none; }
.mx-attach--xs .mx-attach__action { width: 22px; height: 22px; }

/* vertical (image card) */
.mx-attach--vertical {
  flex-direction: column; align-items: stretch; gap: 8px;
  width: 168px; min-width: 0; max-width: none; padding: 8px;
}
.mx-attach--vertical .mx-attach__media { width: 100%; height: 100px; border-radius: var(--mx-radius-sm); }
.mx-attach--vertical .mx-attach__media svg { width: 26px; height: 26px; }
.mx-attach--vertical .mx-attach__content { padding: 0 2px 2px; }
.mx-attach--vertical .mx-attach__actions { position: absolute; top: 14px; right: 14px; }
.mx-attach--vertical .mx-attach__action {
  background: var(--mx-glass); color: var(--mx-ink-soft);
  box-shadow: var(--mx-shadow-xs); backdrop-filter: blur(6px);
}
.mx-attach--vertical .mx-attach__action:hover { color: var(--mx-ink); }
.mx-attach--vertical .mx-attach__progress { left: 8px; right: 8px; bottom: 8px; border-radius: var(--mx-radius-pill); }

/* group — horizontally scrollable row with edge fade + snap */
.mx-attach-group {
  display: flex; gap: 10px; overflow-x: auto; padding: 2px 0 6px;
  scroll-snap-type: x proximity;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
}
.mx-attach-group > .mx-attach { flex: 0 0 auto; scroll-snap-align: start; }

@media (prefers-reduced-motion: reduce) {
  .mx-attach.is-uploading .mx-attach__title,
  .mx-attach.is-processing .mx-attach__title,
  .mx-attach.is-processing .mx-attach__progress-bar { animation: none; }
}

/* --------------------------------------------------------- 27 · Scroll-fade
   Dissolves the edges of a scroll container with mask-image (fades the content
   itself, so it works over any background). Scroll-aware via CSS scroll-driven
   animations: the *starting* edge is crisp at rest and the *ending* edge fades
   to hint there's more — both fade mid-scroll, and the ending edge sharpens at
   the end. No JS. Browsers without scroll-timeline get a static edge fade.
   Adapted from shadcn's scroll-fade utility.

     <ul class="mx-scroll mx-scroll-fade">…</ul>          vertical (top + bottom)
     <div class="mx-scroll-x mx-scroll-fade-x">…</div>    horizontal (left + right)
     class="mx-scroll-fade-t|-b|-l|-r"                     single edge
   Tune depth with the --mx-sf variable (default min(12%, 40px)); the reveal
   easing distance with --mx-sf-reveal (default 96px). --mx-sf-none disables. */
@property --mx-sf-start { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --mx-sf-end   { syntax: "<number>"; inherits: false; initial-value: 0; }

[class*="mx-scroll-fade"] { --mx-sf: min(12%, 40px); --mx-sf-reveal: 96px; }
@keyframes mx-sf-in  { from { --mx-sf-start: 0; } to { --mx-sf-start: 1; } }
@keyframes mx-sf-out { from { --mx-sf-end: 1; }   to { --mx-sf-end: 0; } }

/* vertical — both edges */
.mx-scroll-fade, .mx-scroll-fade-y {
  overflow-y: auto;
  -webkit-mask-image: linear-gradient(to bottom, #0000 0, #000 calc(var(--mx-sf) * var(--mx-sf-start)), #000 calc(100% - var(--mx-sf) * var(--mx-sf-end)), #0000 100%);
          mask-image: linear-gradient(to bottom, #0000 0, #000 calc(var(--mx-sf) * var(--mx-sf-start)), #000 calc(100% - var(--mx-sf) * var(--mx-sf-end)), #0000 100%);
}
/* horizontal — both edges */
.mx-scroll-fade-x {
  overflow-x: auto;
  -webkit-mask-image: linear-gradient(to right, #0000 0, #000 calc(var(--mx-sf) * var(--mx-sf-start)), #000 calc(100% - var(--mx-sf) * var(--mx-sf-end)), #0000 100%);
          mask-image: linear-gradient(to right, #0000 0, #000 calc(var(--mx-sf) * var(--mx-sf-start)), #000 calc(100% - var(--mx-sf) * var(--mx-sf-end)), #0000 100%);
}
/* single edges */
.mx-scroll-fade-t { overflow-y: auto; -webkit-mask-image: linear-gradient(to bottom, #0000 0, #000 calc(var(--mx-sf) * var(--mx-sf-start))); mask-image: linear-gradient(to bottom, #0000 0, #000 calc(var(--mx-sf) * var(--mx-sf-start))); }
.mx-scroll-fade-b { overflow-y: auto; -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - var(--mx-sf) * var(--mx-sf-end)), #0000 100%); mask-image: linear-gradient(to bottom, #000 calc(100% - var(--mx-sf) * var(--mx-sf-end)), #0000 100%); }
.mx-scroll-fade-l { overflow-x: auto; -webkit-mask-image: linear-gradient(to right, #0000 0, #000 calc(var(--mx-sf) * var(--mx-sf-start))); mask-image: linear-gradient(to right, #0000 0, #000 calc(var(--mx-sf) * var(--mx-sf-start))); }
.mx-scroll-fade-r { overflow-x: auto; -webkit-mask-image: linear-gradient(to right, #000 calc(100% - var(--mx-sf) * var(--mx-sf-end)), #0000 100%); mask-image: linear-gradient(to right, #000 calc(100% - var(--mx-sf) * var(--mx-sf-end)), #0000 100%); }

.mx-scroll-fade-none { -webkit-mask-image: none !important; mask-image: none !important; animation: none !important; }

/* Static fallback for browsers without scroll-driven animations:
   pin a permanent fade on the applicable ending edge(s). */
@supports not (animation-timeline: scroll()) {
  .mx-scroll-fade, .mx-scroll-fade-y, .mx-scroll-fade-x,
  .mx-scroll-fade-b, .mx-scroll-fade-r { --mx-sf-end: 1; }
}

/* Scroll-aware behavior where supported. Two animations share the scroll
   timeline; each covers just its reveal band and holds (fill:both) elsewhere,
   so with no overflow the timeline is inert and both vars fall back to 0 = crisp. */
@supports (animation-timeline: scroll()) {
  .mx-scroll-fade, .mx-scroll-fade-y {
    animation: mx-sf-in linear both, mx-sf-out linear both;
    animation-timeline: scroll(self block);
    animation-range: 0 var(--mx-sf-reveal), calc(100% - var(--mx-sf-reveal)) 100%;
  }
  .mx-scroll-fade-x {
    animation: mx-sf-in linear both, mx-sf-out linear both;
    animation-timeline: scroll(self inline);
    animation-range: 0 var(--mx-sf-reveal), calc(100% - var(--mx-sf-reveal)) 100%;
  }
  .mx-scroll-fade-t { animation: mx-sf-in linear both;  animation-timeline: scroll(self block);  animation-range: 0 var(--mx-sf-reveal); }
  .mx-scroll-fade-b { animation: mx-sf-out linear both; animation-timeline: scroll(self block);  animation-range: calc(100% - var(--mx-sf-reveal)) 100%; }
  .mx-scroll-fade-l { animation: mx-sf-in linear both;  animation-timeline: scroll(self inline); animation-range: 0 var(--mx-sf-reveal); }
  .mx-scroll-fade-r { animation: mx-sf-out linear both; animation-timeline: scroll(self inline); animation-range: calc(100% - var(--mx-sf-reveal)) 100%; }
}

/* --------------------------------------------------------- 28 · Shimmer
   An animated highlight sweeps across text — a "…thinking / generating"
   loading state. The text itself is painted with background-clip:text and a
   brighter band travels across it in a seamless loop, so it adapts to any
   background and brightens automatically in dark mode (the band moves toward
   --mx-ink, which flips light↔dark with the theme). Adapted from shadcn's
   shimmer utility.

     <span class="mx-shimmer">Generating response…</span>
     <span class="mx-shimmer mx-shimmer-once">Saved</span>        single sweep
     <span class="mx-shimmer mx-shimmer-reverse">Loading…</span>  reverse

   Tune with --mx-shimmer-fill (base text color, default muted),
   --mx-shimmer-highlight (the sweeping band, default ink), --mx-shimmer-duration
   (default 2s), --mx-shimmer-spread (band half-width, default 24%) and
   --mx-shimmer-angle (default 20deg). .mx-shimmer-none disables the effect.
   Respects prefers-reduced-motion (falls back to static --mx-shimmer-fill). */
.mx-shimmer {
  --mx-shimmer-fill: var(--mx-muted);
  --mx-shimmer-highlight: var(--mx-ink);
  --mx-shimmer-duration: 2s;
  --mx-shimmer-spread: 24%;
  --mx-shimmer-angle: 20deg;
  display: inline-block;
  color: transparent;
  -webkit-text-fill-color: transparent;
  background-image: linear-gradient(
    var(--mx-shimmer-angle),
    var(--mx-shimmer-fill)      calc(50% - var(--mx-shimmer-spread)),
    var(--mx-shimmer-highlight) 50%,
    var(--mx-shimmer-fill)      calc(50% + var(--mx-shimmer-spread))
  );
  background-size: 200% 100%;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
          background-clip: text;
  animation: mx-shimmer-sweep var(--mx-shimmer-duration) linear infinite;
}
@keyframes mx-shimmer-sweep {
  from { background-position: 150% 0; }
  to   { background-position: -50% 0; }
}
.mx-shimmer-once    { animation-iteration-count: 1; }
.mx-shimmer-reverse { animation-direction: reverse; }
.mx-shimmer-none {
  color: var(--mx-shimmer-fill, currentColor);
  -webkit-text-fill-color: var(--mx-shimmer-fill, currentColor);
  background: none;
  animation: none;
}
@media (prefers-reduced-motion: reduce) {
  .mx-shimmer {
    animation: none;
    background: none;
    color: var(--mx-shimmer-fill);
    -webkit-text-fill-color: var(--mx-shimmer-fill);
  }
}

/* Visually-hidden but focusable/functional (used by mxUpload's native input). */
.mx-visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---- Timeline (activity/history feed) -----------------------------------
   <div class="mx-timeline">
     <div class="mx-timeline__item">
       <span class="mx-timeline__point"></span>
       <div class="mx-timeline__body">…</div>
     </div>
   </div>
   Point variants: --brand (default) / --muted. */
.mx-timeline { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.mx-timeline__item {
  position: relative;
  display: flex;
  gap: 14px;
  padding: 0 0 18px 0;
}
.mx-timeline__item::before {
  content: "";
  position: absolute;
  left: 5px;
  top: 14px;
  bottom: 0;
  width: 1px;
  background: var(--mx-line);
}
.mx-timeline__item:last-child { padding-bottom: 0; }
.mx-timeline__item:last-child::before { display: none; }
.mx-timeline__point {
  flex: none;
  width: 11px;
  height: 11px;
  margin-top: 4px;
  border-radius: 999px;
  background: var(--mx-brand-tint);
  border: 2px solid var(--mx-brand);
}
.mx-timeline__point--muted { border-color: var(--mx-line-strong); background: var(--mx-surface-soft); }
.mx-timeline__body { flex: 1 1 auto; min-width: 0; }
.mx-timeline__meta { font-size: var(--mx-text-xs); color: var(--mx-muted); }
.mx-timeline__title { font-size: var(--mx-text-sm); font-weight: 500; color: var(--mx-ink); }
.mx-timeline__note { font-size: var(--mx-text-xs); color: var(--mx-muted); font-style: italic; }
