/* ===========================================================================
 * InfinityCore — Design System CSS (Phase 1 foundation, session 17e)
 *
 * Single source of truth for component styles. Loaded once via <link> from
 * base.html, AFTER tokens.css so CSS variables resolve. Loaded BEFORE the
 * Tailwind CDN script tag so utility classes can still override locally.
 *
 * What lives here:
 *   - Component primitives (button, badge, kpi-card, age-chip, risk-banner,
 *     empty-state, skeleton, toast, modal, drawer)
 *   - Worklist-ready primitives (ds-table, ds-filter-bar, ds-pager) used by
 *     Phase 1.5 lists (returns-due, check-outs-today, overdue, fines, invoices)
 *
 * What does NOT live here:
 *   - Per-screen styles (.cust-table, .veh-table, …) — left in their pages.
 *     Per-screen consolidation is a Phase-17 (per-screen redesign) job, not
 *     a foundation job.
 *
 * Hard rule: NO hardcoded colours or px values. Every rule pulls from
 * tokens.css. If a token doesn't exist, add it to tokens.css first.
 * =========================================================================== */

/* ============================================================
 * BUTTONS
 * ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-family: var(--ff-ui);
  font-weight: 500;
  text-decoration: none;
  border: none;
  border-radius: var(--r-2);
  cursor: pointer;
  transition: background-color var(--t-base), color var(--t-base), opacity var(--t-base);
  white-space: nowrap;
  padding: 0 12px;
}

.btn--sm      { height: 26px; font-size: 11px; }
.btn--default { height: 30px; font-size: 12px; }
.btn--lg      { height: 34px; font-size: 13px; }

.btn--primary { background: var(--ink); color: var(--surface); }
.btn--primary:hover { background: var(--ink-2); }

.btn--accent { background: var(--accent); color: var(--surface); }
.btn--accent:hover { background: var(--accent-2); }

.btn--ghost,
.btn--secondary {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
}
.btn--ghost:hover,
.btn--secondary:hover { background: var(--surface-2); }

.btn--approve {
  background: var(--green-tint);
  color: var(--green-ink);
  border: 1px solid var(--green-ink);
}
.btn--approve:hover { background: var(--green); color: var(--surface); }

.btn--reject,
.btn--destructive,
.btn--danger {
  background: var(--red-tint);
  color: var(--red-ink);
  border: 1px solid var(--red-ink);
}
.btn--reject:hover,
.btn--destructive:hover,
.btn--danger:hover { background: var(--red); color: var(--surface); }

.btn--escalate {
  background: var(--blue-tint);
  color: var(--blue-ink);
  border: 1px solid var(--blue-ink);
}
.btn--escalate:hover { background: var(--blue); color: var(--surface); }

.btn--icon {
  width: 30px;
  height: 30px;
  padding: 0;
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--r-2);
}
.btn--icon:hover { background: var(--surface-2); }

.btn:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-ring-offset); }

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

/* ============================================================
 * STATUS BADGE
 * ============================================================ */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 7px;
  border-radius: var(--r-1);
  font-family: var(--ff-mono);
  font-size: 11px;
  font-weight: 500;
  border: 1px solid;
  white-space: nowrap;
}
.badge__dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.badge__label { text-transform: capitalize; }

/* Colour families. RAC status tokens (vehicle / contract / deposit / approval)
   are mapped to these families once, in core/templatetags/status_extras.py;
   adding a status token here is the single place a colour changes. */
.badge--pending,
.badge--in-garage,            /* vehicle: In Garage   */
.badge--partially-deducted,   /* deposit: Partially Deducted */
.badge--unmatched,            /* violation: Unmatched */
.badge--draft {
  background: var(--amber-tint);
  color: var(--amber-ink);
  border-color: var(--amber-ink);
}
.badge--approved,
.badge--live,
.badge--available,
.badge--active,               /* contract: Active */
.badge--held,                 /* deposit: Held    */
.badge--recovered {           /* violation: Recovered */
  background: var(--green-tint);
  color: var(--green-ink);
  border-color: var(--green-ink);
}
.badge--rejected,
.badge--overdue,
.badge--accident,             /* vehicle: Accident */
.badge--forfeited,            /* deposit: Forfeited */
.badge--disputed,             /* violation: Disputed */
.badge--on-hold {             /* vehicle: On Hold (kept red, consistent everywhere) */
  background: var(--red-tint);
  color: var(--red-ink);
  border-color: var(--red-ink);
}
.badge--escalated,
.badge--reserved,
.badge--returned,             /* contract: Returned */
.badge--refund-pending,       /* deposit: Refund Pending */
.badge--matched,              /* violation: Matched */
.badge--pending-recovery {    /* violation: Pending Recovery */
  background: var(--blue-tint);
  color: var(--blue-ink);
  border-color: var(--blue-ink);
}
.badge--withdrawn,
.badge--closed,
.badge--inactive,
.badge--cancelled,            /* contract: Cancelled */
.badge--refunded,             /* deposit: Refunded   */
.badge--written-off {         /* violation: Written Off */
  background: var(--surface-2);
  color: var(--muted);
  border-color: var(--line);
}
.badge--draft { border-style: dashed; }

/* RAC orange — Rented vehicles. Mirrors the --fs-rented fleet pill so the
   badge and the fleet-status pill agree on what "Rented" looks like. */
.badge--rented {
  background: var(--accent-tint);
  color: var(--accent-2);
  border-color: var(--accent-2);
}

.badge--pending .badge__dot,
.badge--in-garage .badge__dot,
.badge--partially-deducted .badge__dot,
.badge--unmatched .badge__dot { background: var(--amber-ink); }
.badge--approved .badge__dot,
.badge--live .badge__dot,
.badge--available .badge__dot,
.badge--active .badge__dot,
.badge--held .badge__dot,
.badge--recovered .badge__dot { background: var(--green-ink); }
.badge--rejected .badge__dot,
.badge--overdue .badge__dot,
.badge--accident .badge__dot,
.badge--forfeited .badge__dot,
.badge--disputed .badge__dot,
.badge--on-hold .badge__dot   { background: var(--red-ink); }
.badge--escalated .badge__dot,
.badge--reserved .badge__dot,
.badge--returned .badge__dot,
.badge--refund-pending .badge__dot,
.badge--matched .badge__dot,
.badge--pending-recovery .badge__dot { background: var(--blue-ink); }
.badge--rented .badge__dot    { background: var(--accent-2); }
.badge--withdrawn .badge__dot,
.badge--closed .badge__dot,
.badge--inactive .badge__dot,
.badge--cancelled .badge__dot,
.badge--refunded .badge__dot,
.badge--written-off .badge__dot,
.badge--draft .badge__dot     { background: var(--muted); }

/* ============================================================
 * KPI CARD
 * ============================================================ */
.kpi-card {
  display: block;
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  text-decoration: none;
  color: inherit;
  transition: background-color var(--t-base), border-color var(--t-base);
}
.kpi-card:hover { background: var(--surface-2); }
.kpi-card:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-ring-offset); }

.kpi-card__label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 6px;
}
.kpi-card__value-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 6px;
}
.kpi-card__value {
  font-family: var(--ff-mono);
  font-size: 22px;
  font-weight: 500;
  color: var(--ink);
}
.kpi-card__of { font-size: 13px; color: var(--muted); font-family: var(--ff-mono); }
.kpi-card__sub { font-size: 12px; color: var(--muted); }

.kpi-card--rail-warning {
  border-left: 3px solid var(--amber-ink);
  padding-left: calc(16px - 3px);
}
.kpi-card--rail-danger {
  border-left: 3px solid var(--red-ink);
  padding-left: calc(16px - 3px);
}

/* ============================================================
 * AGE CHIP
 * ============================================================ */
.age-chip {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  font-family: var(--ff-mono);
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
}
.age-chip--neutral { background: var(--surface-2); color: var(--muted); }
.age-chip--warning { background: var(--amber-tint); color: var(--amber-ink); }
.age-chip--danger  { background: var(--red-tint);   color: var(--red-ink); }

/* ============================================================
 * RISK BANNER
 * ============================================================ */
.risk-banner {
  width: 100%;
  padding: 12px 16px;
  border-radius: var(--r-2);
  font-size: 13px;
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}
.risk-banner--warning {
  background: var(--amber-tint);
  color: var(--amber-ink);
  border: 1px solid var(--amber-ink);
}
.risk-banner--danger {
  background: var(--red-tint);
  color: var(--red-ink);
  border: 1px solid var(--red-ink);
}
.risk-banner__content { display: flex; align-items: center; gap: 12px; flex: 1; }
.risk-banner__message { flex: 1; }
.risk-banner__action {
  font-weight: 500;
  text-decoration: underline;
  color: inherit;
  white-space: nowrap;
}
.risk-banner__action:hover { opacity: 0.8; }
.risk-banner__action:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: var(--focus-ring-offset);
}

/* ============================================================
 * EMPTY STATE
 * ============================================================ */
.empty-state {
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-3);
  padding: 32px;
  text-align: center;
}
.empty-state__icon { margin-bottom: 12px; color: var(--muted); display: inline-flex; }
.empty-state__icon svg { width: 24px; height: 24px; stroke-width: 1.5; }
.empty-state__title {
  font-size: var(--t-h3);
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 6px 0;
}
.empty-state__message { font-size: 13px; color: var(--muted); margin: 0 0 12px 0; }

/* ============================================================
 * SKELETON
 * ============================================================ */
.skeleton { animation: shimmer 1.2s infinite; }
.skeleton__line {
  background: linear-gradient(
    90deg,
    var(--surface-2) 0%,
    var(--surface-3) 50%,
    var(--surface-2) 100%
  );
  background-size: 200% 100%;
  border-radius: var(--r-2);
}
@keyframes shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ============================================================
 * TOAST
 * ============================================================ */
.toast {
  position: fixed;
  bottom: 16px;
  right: 16px;
  padding: 12px 16px;
  border-radius: var(--r-2);
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 13px;
  box-shadow: var(--shadow-toast);
  z-index: var(--z-toast);
  max-width: 360px;
}
.toast--success {
  background: var(--green-tint);
  color: var(--green-ink);
  border: 1px solid var(--green-ink);
}
.toast--error {
  background: var(--red-tint);
  color: var(--red-ink);
  border: 1px solid var(--red-ink);
}
.toast--info {
  background: var(--blue-tint);
  color: var(--blue-ink);
  border: 1px solid var(--blue-ink);
}
.toast__message { flex: 1; }
.toast__close {
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  color: currentColor;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.toast__close:hover { opacity: 0.8; }
.toast__close:focus-visible { outline: 2px solid currentColor; outline-offset: var(--focus-ring-offset); }

/* ============================================================
 * MODAL  (shared by modal + typed_confirm — no more duplication)
 * ============================================================ */
.modal-scrim {
  position: fixed;
  inset: 0;
  background: rgba(20, 20, 20, 0.42);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-slow);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: var(--z-modal);
}
.modal-scrim.is-open { opacity: 1; pointer-events: auto; }

.modal {
  background: var(--surface);
  border-radius: var(--r-3);
  box-shadow: var(--shadow-3);
  max-width: 560px;
  width: 90%;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transform: scale(0.95);
  transition: opacity var(--t-slow), transform var(--t-slow);
}
.modal-scrim.is-open .modal { opacity: 1; transform: scale(1); }

.modal__header {
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}
.modal__title { font-size: var(--t-h2); font-weight: 600; margin: 0; color: var(--ink); }

.modal__close {
  background: transparent;
  border: none;
  padding: 4px;
  cursor: pointer;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-2);
}
.modal__close:hover { background: var(--surface-2); color: var(--ink); }
.modal__close:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-ring-offset); }

.modal__body   { flex: 1; overflow-y: auto; padding: 16px 20px; }
.modal__footer {
  padding: 16px 20px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  flex-shrink: 0;
}

/* Typed-confirm modal extras */
.modal__typed-label {
  display: block;
  font-size: 12px;
  font-weight: 500;
  margin-bottom: 6px;
  color: var(--ink);
  margin-top: 16px;
}
.modal__typed-label code {
  background: var(--surface-2);
  padding: 2px 6px;
  border-radius: var(--r-1);
  font-family: var(--ff-mono);
}
.modal__typed-input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  font-family: var(--ff-mono);
  font-size: 12px;
}

/* ============================================================
 * DRAWER (right-side detail panel, 540 px)
 * ============================================================ */
.drawer-scrim {
  position: fixed;
  inset: 0;
  background: rgba(20, 20, 20, 0.42);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-slow);
  z-index: var(--z-drawer);
}
.drawer-scrim.is-open { opacity: 1; pointer-events: auto; }

.drawer {
  position: fixed;
  right: 0;
  top: 0;
  bottom: 0;
  width: 540px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-drawer);
  transform: translateX(100%);
  transition: transform var(--t-slow);
  z-index: var(--z-drawer);
}
.drawer.is-open { transform: translateX(0); }

.drawer__header {
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}
.drawer__title { font-size: var(--t-h2); font-weight: 600; margin: 0; color: var(--ink); }
.drawer__close {
  background: transparent;
  border: none;
  padding: 4px;
  cursor: pointer;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-2);
}
.drawer__close:hover { background: var(--surface-2); color: var(--ink); }
.drawer__close:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.drawer__body   { flex: 1; overflow-y: auto; padding: 20px; }
.drawer__footer {
  padding: 16px 20px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  flex-shrink: 0;
}
@media (max-width: 768px) { .drawer { width: 100%; } }

/* ============================================================
 * FLEET STRIP (Owner Dashboard — 5/6-cell horizontal bar)
 * ============================================================ */
.fleet-strip {
  display: flex;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  overflow: hidden;
}
.fleet-strip__cell {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  cursor: pointer;
  transition: background-color var(--t-base);
  min-width: 0;
}
.fleet-strip__cell:hover { background: var(--surface-2); }
.fleet-strip__cell:focus-visible { outline: var(--focus-ring); outline-offset: -1px; }
.fleet-strip__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--muted);
}
.fleet-strip__dot--active      { background: var(--green-ink); }
.fleet-strip__dot--idle        { background: var(--amber-ink); }
.fleet-strip__dot--maintenance { background: var(--blue-ink); }
.fleet-strip__dot--inactive    { background: var(--red-ink); }
.fleet-strip__label { font-size: 12px; font-weight: 500; color: var(--ink-2); min-width: 0; }
.fleet-strip__count { font-size: 12px; font-weight: 500; color: var(--ink); flex-shrink: 0; }
.fleet-strip__pct   { font-size: 11px; color: var(--muted); flex-shrink: 0; }
.fleet-strip__divider { width: 1px; background: var(--line-soft); align-self: stretch; }

/* ============================================================
 * WORKLIST PRIMITIVES (Phase 1.5 — used by returns-due, check-outs-today,
 * overdue, fines, invoices). Apply via class="ds-table", "ds-filter-bar",
 * "ds-pager" — no per-screen prefix. Existing per-app tables (.cust-table,
 * .veh-table, …) remain untouched; Phase 17 (per-screen redesign) is where
 * those get migrated to use ds-table.
 * ============================================================ */

/* Filter bar — single horizontal row of labelled selects + actions. */
.ds-filter-bar {
  display: grid;
  grid-template-columns: 2fr repeat(4, 1fr) auto;
  gap: 10px;
  align-items: end;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  padding: 14px 16px;
  margin-bottom: 16px;
}
.ds-filter-bar__field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ds-filter-bar__field--grow { grid-column: span 1; }
.ds-filter-bar__label {
  font-size: 11px;
  font-weight: 500;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.ds-filter-bar__input,
.ds-filter-bar__select {
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--ff-ui);
  font-size: 12px;
}
.ds-filter-bar__actions { display: flex; align-items: center; gap: 10px; }
.ds-filter-bar__reset {
  font-size: 12px;
  color: var(--muted);
  text-decoration: underline;
}
.ds-filter-bar__reset:hover { color: var(--ink); }
@media (max-width: 1100px) {
  .ds-filter-bar { grid-template-columns: 1fr 1fr 1fr; }
  .ds-filter-bar__actions { grid-column: 1 / -1; justify-content: flex-end; }
}

/* Worklist-ready table — dense, scannable, with hover + selected + empty. */
.ds-table-wrap {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  overflow: hidden;
}
.ds-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.ds-table thead th {
  text-align: left;
  padding: 10px 14px;
  background: var(--surface-2);
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.ds-table thead th.is-sortable { cursor: pointer; user-select: none; }
.ds-table thead th.is-sortable:hover { color: var(--ink-2); }
.ds-table thead th.is-sorted-asc::after  { content: " \2191"; color: var(--ink-2); }
.ds-table thead th.is-sorted-desc::after { content: " \2193"; color: var(--ink-2); }

.ds-table tbody td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--line-soft);
  color: var(--ink-2);
  vertical-align: middle;
}
.ds-table tbody tr:last-child td { border-bottom: 0; }
.ds-table__row:hover { background: var(--surface-2); }
.ds-table__row.is-selected { background: var(--accent-tint); }

/* Severity row tints — opt-in modifier classes for worklist urgency. */
.ds-table__row--warn      { background: var(--amber-tint); }
.ds-table__row--warn:hover  { background: var(--amber-tint); }
.ds-table__row--alert     { background: var(--red-tint); }
.ds-table__row--alert:hover { background: var(--red-tint); }
.ds-table__row--muted     { color: var(--muted); }

.ds-table__cell { color: var(--ink-2); }
.ds-table__muted { color: var(--muted); }
.ds-table__num   { font-family: var(--ff-mono); font-feature-settings: "tnum" 1; text-align: right; }
.ds-table__link  { color: var(--ink); font-weight: 500; text-decoration: none; }
.ds-table__link:hover { text-decoration: underline; }
.ds-table__sub   { font-size: 11px; color: var(--muted); margin-top: 2px; }

/* Pager — count on the left, prev/next on the right. */
.ds-pager {
  margin-top: 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.ds-pager__count { font-size: 12px; color: var(--muted); }
.ds-pager__nav   { display: flex; gap: 8px; }

/* ============================================================
 * MONEY — paired with the |qar template filter. Negative amounts get
 * a red wrapper class so accounting can spot them at a glance.
 * ============================================================ */
.ds-money              { font-family: var(--ff-mono); font-feature-settings: "tnum" 1; }
.ds-money--neg         { color: var(--money-neg-ink); }
.ds-money--zero        { color: var(--muted); }

/* ============================================================
 * FLEET-STATUS PILL — small inline pill that takes its colour from the
 * --fs-* alias tokens. Use class="ds-fs-pill ds-fs-pill--rented" etc.
 * ============================================================ */
.ds-fs-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 8px;
  border-radius: var(--r-pill);
  font-family: var(--ff-mono);
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
}
.ds-fs-pill--available { background: var(--fs-available-bg); color: var(--fs-available-ink); }
.ds-fs-pill--reserved  { background: var(--fs-reserved-bg);  color: var(--fs-reserved-ink); }
.ds-fs-pill--rented    { background: var(--fs-rented-bg);    color: var(--fs-rented-ink); }
.ds-fs-pill--garage,
.ds-fs-pill--in-garage { background: var(--fs-garage-bg);    color: var(--fs-garage-ink); }
.ds-fs-pill--accident  { background: var(--fs-accident-bg);  color: var(--fs-accident-ink); }
.ds-fs-pill--inactive  { background: var(--fs-inactive-bg);  color: var(--fs-inactive-ink); }
.ds-fs-pill--blocked   { background: var(--fs-blocked-bg);   color: var(--fs-blocked-ink); }
.ds-fs-pill--overdue   { background: var(--fs-overdue-bg);   color: var(--fs-overdue-ink); }

/* ============================================================
 * FLASH MESSAGES (Django messages framework — used by base.html)
 * Stacked vertically; one variant per Django tag (error/success/warning/info).
 * ============================================================ */
.ds-messages > * + * { margin-top: 8px; }
.ds-message {
  border-radius: var(--r-2);
  border-left: 4px solid;
  padding: 8px 14px;
  font-size: 13px;
}
.ds-message--error {
  border-left-color: var(--red);
  background: var(--red-tint);
  color: var(--red-ink);
}
.ds-message--success {
  border-left-color: var(--green);
  background: var(--green-tint);
  color: var(--green-ink);
}
.ds-message--warning {
  border-left-color: var(--amber);
  background: var(--amber-tint);
  color: var(--amber-ink);
}
.ds-message--info {
  border-left-color: var(--blue);
  background: var(--blue-tint);
  color: var(--blue-ink);
}

/* ============================================================
 * SURFACE CARD
 * Plain bordered surface — the workhorse used to host forms, sections,
 * profile blocks, etc. Replaces dozens of inline
 *   class="bg-white border border-slate-200 rounded p-5"
 * Tailwind chains across raw screens.
 * ============================================================ */
.ds-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  padding: 20px;
}
.ds-card--soft { background: var(--surface-2); }
.ds-card--accent { border-color: var(--accent); }
.ds-card--success { border-color: var(--green-ink); background: var(--green-tint); }
.ds-card--danger  { border-color: var(--red-ink);   background: var(--red-tint); }
.ds-card--warning { border-color: var(--amber-ink); background: var(--amber-tint); }
.ds-card--info    { border-color: var(--blue-ink);  background: var(--blue-tint); }
.ds-card__heading {
  font-size: var(--t-h3);
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 12px 0;
}
.ds-card__sub {
  font-size: 12px;
  color: var(--muted);
  margin: -8px 0 12px 0;
}
.ds-card + .ds-card { margin-top: 16px; }

/* ============================================================
 * KPI STRIP — Owner Dashboard, Approval Inbox, Customer Detail.
 * 4-column grid that collapses to 2 on tablet, 1 on phone. Existing
 * .apr-kpi-strip / .cust-kpi-strip stay (tests assert on those names);
 * new screens should use .ds-kpi-strip directly.
 * ============================================================ */
.ds-kpi-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 20px;
}
.ds-kpi-strip--3 { grid-template-columns: repeat(3, 1fr); }
.ds-kpi-strip--2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 1100px) { .ds-kpi-strip,
                              .ds-kpi-strip--3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px)  { .ds-kpi-strip,
                              .ds-kpi-strip--3,
                              .ds-kpi-strip--2 { grid-template-columns: 1fr; } }

/* ============================================================
 * FORM PRIMITIVES — used by every "new X" / "edit X" screen.
 * Replaces the
 *   class="mt-1 block w-full rounded border-slate-300 px-3 py-2 text-sm border"
 * Tailwind chain that was duplicated across customers/form, contracts/form,
 * users/form, etc.
 * ============================================================ */
.ds-form { display: flex; flex-direction: column; gap: 16px; }
.ds-form--narrow { max-width: 720px; }
.ds-form--wide   { max-width: 1080px; }

.ds-form__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}
@media (min-width: 720px) {
  .ds-form__grid--2 { grid-template-columns: 1fr 1fr; }
}
.ds-form__field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ds-form__field--wide { grid-column: 1 / -1; }

.ds-form__label {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-2);
}
.ds-form__required { color: var(--red-ink); margin-left: 2px; }

.ds-form__input,
.ds-form__select,
.ds-form__textarea {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--ff-ui);
  font-size: 13px;
  line-height: 1.4;
}
.ds-form__input--mono { font-family: var(--ff-mono); font-feature-settings: "tnum" 1; }
.ds-form__textarea { resize: vertical; min-height: 64px; }
.ds-form__input:focus-visible,
.ds-form__select:focus-visible,
.ds-form__textarea:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
  border-color: var(--accent);
}
.ds-form__hint {
  font-size: 11px;
  color: var(--muted);
}
.ds-form__error {
  font-size: 11px;
  color: var(--red-ink);
  margin-top: 2px;
}

.ds-form__actions {
  display: flex;
  gap: 8px;
  align-items: center;
  padding-top: 12px;
  border-top: 1px solid var(--line-soft);
  flex-wrap: wrap;
}

/* Sticky form-action bar — keeps Save + Cancel pinned to the viewport
   bottom so long forms (Add New Customer / Vehicle / Contract) never
   leave the primary action out of view. Sits inside the ds-card form,
   so it inherits the card's horizontal padding. */
.ds-form__actions--sticky {
  position: sticky;
  bottom: 0;
  z-index: 5;
  margin: 16px -20px -20px -20px;
  padding: 12px 20px;
  background: var(--surface);
  border-top: 1px solid var(--line);
  border-bottom-left-radius: var(--r-3);
  border-bottom-right-radius: var(--r-3);
  box-shadow: 0 -4px 12px -8px rgba(20, 20, 20, 0.08);
}

.ds-form__summary {
  padding: 12px 16px;
  border-radius: var(--r-2);
  background: var(--surface-2);
  border: 1px solid var(--line);
  font-size: 13px;
  color: var(--ink-2);
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: baseline;
}
.ds-form__summary strong { font-family: var(--ff-mono); color: var(--ink); }

/* Inline warning shown under a select (e.g. "customer is unverified"). */
.ds-form__notice {
  margin-top: 4px;
  padding: 6px 10px;
  font-size: 11px;
  border-radius: var(--r-2);
  border: 1px solid var(--amber-ink);
  background: var(--amber-tint);
  color: var(--amber-ink);
}

/* ============================================================
 * INLINE-ERROR — small red helper used next to a button when an
 * in-page AJAX action fails. Replaces window.alert().
 * ============================================================ */
.ds-inline-error {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  border-radius: var(--r-1);
  background: var(--red-tint);
  color: var(--red-ink);
  border: 1px solid var(--red-ink);
  font-size: 11px;
  vertical-align: middle;
}
.ds-inline-error[hidden] { display: none !important; }

/* ============================================================
 * RTL READINESS
 *
 * The chrome is left-anchored (sidebar 232 px left, content margin-left:
 * 232px). For Arabic we'll flip to dir="rtl" on <html>. These overrides
 * mirror the left-anchored chrome so the layout doesn't break.
 * Nothing is translated here — that's a future content task.
 * ============================================================ */
[dir="rtl"] .app-sidebar {
  inset: 0 0 0 auto;            /* right-anchored */
  border-right: 0;
  border-left: 1px solid var(--sidebar-ln);
}
[dir="rtl"] .app-main           { margin-left: 0; margin-right: 232px; }
[dir="rtl"] .app-sidebar__item  { border-left: 0; border-right: 3px solid transparent; }
[dir="rtl"] .app-sidebar__item.is-active { border-right-color: var(--accent); }

[dir="rtl"] .drawer             { right: auto; left: 0; transform: translateX(-100%); }
[dir="rtl"] .drawer.is-open     { transform: translateX(0); }

[dir="rtl"] .toast              { right: auto; left: 16px; }

[dir="rtl"] .ds-table thead th  { text-align: right; }
[dir="rtl"] .ds-table__num      { text-align: left; }

[dir="rtl"] .ds-inline-error    { margin-left: 0; margin-right: 8px; }
[dir="rtl"] .ds-form__required  { margin-left: 0; margin-right: 2px; }
