/* ============================================================
   components.css — GENERATED by scripts/build-css.js
   Do NOT edit directly. Edit public-html/styles/src/components/** and
   run: npm run build:css
   ============================================================ */

/* ── src/components/00-icon.css ─────────────────────────────────── */
/* ============================================================
   ICON  (.ak-icon)  — Contract §11
   Icon architecture: **Font Awesome is retained** as the canonical
   project icon system. `.ak-icon` is a thin abstraction LAYER over
   Font Awesome — it standardises sizing / alignment / colour and
   is what component markup and the future React <Icon> wrap.

   Usage:  <i class="ak-icon fa-solid fa-user" aria-hidden="true"></i>
   (any Font Awesome class set works alongside .ak-icon).
   ============================================================ */

.ak-icon {
  /* Base = inherit the surrounding text size, so adding .ak-icon to an
     existing Font Awesome <i> is visually a no-op. Use the size modifiers
     (--xs … --xl) for an explicit icon size. */
  font-size: 1em;
  line-height: 1;
  color: currentColor;
  flex: 0 0 auto;
}
/* if an inline <svg> is ever used for a bespoke asset, keep it sized too */
.ak-icon > svg { inline-size: 1em; block-size: 1em; display: block; }

.ak-icon--xs { inline-size: var(--icon-xs); block-size: var(--icon-xs); font-size: var(--icon-xs); }
.ak-icon--sm { inline-size: var(--icon-sm); block-size: var(--icon-sm); font-size: var(--icon-sm); }
.ak-icon--lg { inline-size: var(--icon-lg); block-size: var(--icon-lg); font-size: var(--icon-lg); }
.ak-icon--xl { inline-size: var(--icon-xl); block-size: var(--icon-xl); font-size: var(--icon-xl); }

/* directional icons flip in RTL; add .ak-icon--fixed to opt out */
[dir="rtl"] .ak-icon--dir:not(.ak-icon--fixed) { transform: scaleX(-1); }

.ak-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 40px;
  block-size: 40px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-secondary);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-standard), color var(--dur-fast);
}
.ak-icon-btn:hover { background: var(--color-primary-subtle); color: var(--color-text-primary); }
.ak-icon-btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.ak-icon-btn:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; }
.ak-icon-btn--sm { inline-size: 32px; block-size: 32px; }
.ak-icon-btn--danger:hover { color: var(--color-error); background: rgba(var(--color-error-rgb), .08); border-color: var(--color-error); }
.ak-icon-btn--edit:hover { color: var(--color-info); background: rgba(var(--color-info-rgb), .08); border-color: var(--color-info); }
.ak-icon-btn--success:hover { color: var(--color-success); background: rgba(var(--color-success-rgb), .08); border-color: var(--color-success); }
.ak-icon-btn--bordered { border-color: var(--color-border-subtle); background: var(--color-surface); }

/* ── src/components/01-button.css ─────────────────────────────────── */
/* ============================================================
   BUTTON  (.ak-btn)  — ARAKA Design System Contract §13
   Premium, token-based, one system. 6 variants × 3 sizes × 6 states.
   Migration target for legacy .btn / .btn-* / .admin-btn-*.
   ============================================================ */

:root .ak-btn {
  --_bg: var(--color-primary);
  --_fg: var(--color-text-on-primary);
  --_bg-hover: var(--color-primary-hover);
  --_border: transparent;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 40px;                 /* md */
  padding-block: var(--space-2);
  padding-inline: var(--space-5);
  border: 1px solid var(--_border);
  border-radius: var(--radius-md);
  background: var(--_bg);
  color: var(--_fg);
  font-family: var(--font-family-base);
  font-size: var(--text-body);
  font-weight: var(--fw-semibold);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition:
    background-color var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard),
    box-shadow var(--dur-fast) var(--ease-standard),
    transform var(--dur-fast) var(--ease-standard);
}

.ak-btn > .ak-icon,
.ak-btn > svg,
.ak-btn > i { flex: 0 0 auto; font-size: var(--icon-sm); width: var(--icon-sm); height: var(--icon-sm); }

/* — states — */
@media (hover: hover) {
  :root .ak-btn:hover{ background: var(--_bg-hover); box-shadow: var(--elevation-1); }
}
:root .ak-btn:active{ transform: translateY(1px); box-shadow: none; }
:root .ak-btn:focus-visible{
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
:root .ak-btn:disabled,
:root .ak-btn[aria-disabled="true"]{
  opacity: var(--opacity-disabled);
  cursor: not-allowed;
  pointer-events: none;
  transform: none;
  box-shadow: none;
}
:root .ak-btn[data-loading="true"]{
  color: transparent;
  pointer-events: none;
  position: relative;
}
:root .ak-btn[data-loading="true"]::after{
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  width: 16px; height: 16px;
  margin: -8px 0 0 -8px;
  border: 2px solid currentColor;
  border-block-start-color: transparent;
  border-radius: var(--radius-full);
  color: var(--_fg);
  animation: ak-spin 0.7s linear infinite;
}
@keyframes ak-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  :root .ak-btn { transition: none; }
  :root .ak-btn[data-loading="true"]::after{ animation-duration: 1.4s; }
}

/* — variants — */
:root .ak-btn--secondary {
  --_bg: var(--color-navy);
  --_fg: var(--color-text-on-navy);
  --_bg-hover: var(--dark-navy);
}
:root .ak-btn--outline {
  --_bg: transparent;
  --_fg: var(--color-primary-ink);    /* legible brand tone; pure amber is unreadable as text */
  --_border: var(--color-primary);
  --_bg-hover: var(--color-primary-subtle);
}
:root .ak-btn--outline:hover{ color: var(--color-primary-ink); }
:root .ak-btn--ghost {
  --_bg: transparent;
  --_fg: var(--color-text-primary);
  --_border: transparent;
  --_bg-hover: var(--color-primary-subtle);
}
:root .ak-btn--danger {
  --_bg: var(--color-error);
  --_fg: #fff;
  --_bg-hover: #c0392b;
}
/* success / warning — used by admin domain actions (accept bid, etc.);
   not general-purpose (Contract §13). */
:root .ak-btn--success {
  --_bg: var(--color-success);
  --_fg: #fff;
  --_bg-hover: #27ae60;
}
:root .ak-btn--warning {
  --_bg: var(--color-warning);
  --_fg: #fff;
  --_bg-hover: #d35400;
}
:root .ak-btn--link {
  --_bg: transparent;
  --_fg: var(--color-primary-ink);
  --_border: transparent;
  padding-inline: var(--space-1);
  min-height: 0;
  font-weight: var(--fw-medium);
  text-decoration: underline;
  text-underline-offset: 3px;
}
:root .ak-btn--link:hover{ background: transparent; color: var(--color-primary-active); }
:root .ak-btn--icon {
  --_bg: transparent;
  --_fg: var(--color-text-secondary);
  --_bg-hover: var(--color-primary-subtle);
  padding-inline: 0;
  width: 40px;
  min-height: 40px;
}
:root .ak-btn--icon:hover{ color: var(--color-text-primary); }

/* — sizes — */
:root .ak-btn--sm {
  min-height: 32px;
  padding-block: var(--space-1);
  padding-inline: var(--space-3);
  font-size: var(--text-body-sm);
  gap: var(--space-1);
}
:root .ak-btn--sm.ak-btn--icon{ width: 32px; }
:root .ak-btn--lg {
  min-height: 48px;
  padding-inline: var(--space-6);
  font-size: var(--text-body-lg);
}
:root .ak-btn--lg.ak-btn--icon{ width: 48px; }

/* — layout — */
:root .ak-btn--block { display: flex; width: 100%; }

:root .ak-btn-group {
  display: inline-flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* — Refresh / retry buttons — every "بروزرسانی"/"تلاش مجدد" button project-
   wide (admin + user) is a normal .ak-btn carrying a fa-sync / fa-sync-alt /
   fa-rotate-right / fa-redo icon; there is no separate component class for
   these. Scoping by the icon class (rather than adding a new marker class
   to every button in every template) reaches every current instance and any
   future one automatically, in both apps, with one rule. Two independent
   effects: a subtle hover tilt (distinct from the button's own hover) and a
   full-turn spin on click, restarted via the .ak-spin-once class toggled by
   js/shared/refresh-spin.js. */
:root button:hover .fa-sync,
:root a:hover .fa-sync,
:root button:hover .fa-sync-alt,
:root a:hover .fa-sync-alt,
:root button:hover .fa-rotate-right,
:root a:hover .fa-rotate-right,
:root button:hover .fa-redo,
:root a:hover .fa-redo {
  transform: rotate(55deg);
}
:root .fa-sync,
:root .fa-sync-alt,
:root .fa-rotate-right,
:root .fa-redo {
  display: inline-block;
  transition: transform var(--dur-base) var(--ease-standard);
}
:root .ak-spin-once {
  animation: ak-spin-once 0.7s cubic-bezier(0.4, 0, 0.2, 1);
}
@keyframes ak-spin-once {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  :root .fa-sync,
  :root .fa-sync-alt,
  :root .fa-rotate-right,
  :root .fa-redo { transition: none; }
  :root .ak-spin-once { animation: none; }
}

/* ── src/components/02-field.css ─────────────────────────────────── */
/* ============================================================
   FORM FIELD  (.ak-field)  — Contract §14
   Label · RequiredStar · Control · HelperText · Message
   Shared by User + Admin. Migration target for
   .form-group/.form-input + .admin-form-group/.admin-form-input.
   ============================================================ */

.ak-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.ak-field__label {
  font-size: var(--text-body-sm);
  font-weight: var(--fw-medium);
  color: var(--color-text-primary);
}
.ak-field__req {
  color: var(--color-error);
  font-size: 0.7em;
  vertical-align: super;
  margin-inline-start: 3px;
}
.ak-field__optional {
  color: var(--color-text-muted);
  font-weight: var(--fw-regular);
  margin-inline-start: 4px;
}

/* — control — */
:root .ak-input,
:root .ak-select,
:root .ak-textarea {
  width: 100%;
  min-height: 44px;
  padding-block: var(--space-3);
  padding-inline: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font-family: var(--font-family-base);
  font-size: var(--text-body);
  line-height: var(--lh-snug);
  transition:
    border-color var(--dur-fast) var(--ease-standard),
    box-shadow var(--dur-fast) var(--ease-standard);
}
:root .ak-textarea { min-height: 96px; resize: vertical; }
:root .ak-select { appearance: none; padding-inline-end: var(--space-8); cursor: pointer; }

:root .ak-input::placeholder,

:root .ak-textarea::placeholder{ color: var(--color-text-muted); }

:root .ak-input:focus-visible,

:root .ak-select:focus-visible,

:root .ak-textarea:focus-visible{
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

:root .ak-input:disabled,

:root .ak-select:disabled,

:root .ak-textarea:disabled{
  opacity: var(--opacity-disabled);
  cursor: not-allowed;
  background: var(--color-surface);
}

/* — validation states (driven by aria-invalid / data-state) — */
.ak-field[data-state="error"] .ak-input,
.ak-field[data-state="error"] .ak-select,
.ak-field[data-state="error"] .ak-textarea,
[aria-invalid="true"].ak-input,
[aria-invalid="true"].ak-select,
[aria-invalid="true"].ak-textarea {
  border-color: var(--color-error);
  border-width: 2px;
}
.ak-field[data-state="success"] .ak-input { border-color: var(--color-success); }

.ak-field__help {
  font-size: var(--text-body-sm);
  color: var(--color-text-secondary);
  line-height: var(--lh-snug);
}
.ak-field__msg {
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
  font-size: var(--text-body-sm);
  font-weight: var(--fw-medium);
  line-height: var(--lh-snug);
}
.ak-field[data-state="error"] .ak-field__msg { color: var(--color-error); }
.ak-field[data-state="success"] .ak-field__msg { color: var(--color-success); }

/* — input with leading/trailing adornment — */
:root .ak-input-wrap { position: relative; display: flex; align-items: center; }
.ak-input-wrap .ak-input { padding-inline-end: var(--space-10); }
:root .ak-input-wrap__end {
  position: absolute;
  inset-inline-end: var(--space-3);
  display: inline-flex;
  color: var(--color-text-muted);
}

/* — LTR islands (phone / email / code / url) — */
:root .ak-input--ltr {
  direction: ltr;
  text-align: start;
  unicode-bidi: isolate;
}

/* — checkbox / radio / switch — */
:root .ak-check {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  font-size: var(--text-body);
}
.ak-check input { width: 18px; height: 18px; accent-color: var(--color-primary); cursor: pointer; }
.ak-check input:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* — a row of .ak-check options (radio group / checkbox group) — */
:root .ak-check-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-5);
}

/* — toggle switch (view/create-style binary settings, e.g. dashboard-config admin rows) — */
:root .ak-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  font-size: var(--text-body-sm, var(--text-body));
  user-select: none;
}
.ak-switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
:root .ak-switch__track {
  position: relative;
  flex-shrink: 0;
  width: 36px;
  height: 20px;
  border-radius: var(--radius-full);
  background: var(--color-border-strong);
  transition: background-color var(--dur-fast) var(--ease-standard);
}
:root .ak-switch__track::after {
  content: '';
  position: absolute;
  top: 2px;
  inset-inline-start: 2px;
  width: 16px;
  height: 16px;
  border-radius: var(--radius-full);
  background: var(--color-surface-elevated);
  transition: inset-inline-start var(--dur-fast) var(--ease-standard);
}
.ak-switch input:checked + .ak-switch__track { background: var(--color-primary); }
.ak-switch input:checked + .ak-switch__track::after { inset-inline-start: 18px; }
.ak-switch input:focus-visible + .ak-switch__track { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.ak-switch input:disabled + .ak-switch__track { opacity: 0.5; cursor: not-allowed; }

@media (prefers-reduced-motion: reduce) {
  :root .ak-input,
  :root .ak-select,
  :root .ak-textarea { transition: none; }
}

/* ── src/components/03-surface.css ─────────────────────────────────── */
/* ============================================================
   SURFACES  — Contract §11 / §15
   Coherent hierarchy: page bg < surface < elevated < floating.
   Not everything is a card. Low elevation by default.
   ============================================================ */

:root .ak-card {
  background: var(--color-surface-elevated);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-lg);
}
/* Padding is opt-in via .ak-card--pad. During the additive migration the
   legacy *-card class keeps owning padding (existing internal layouts
   untouched); standalone new cards use `ak-card ak-card--pad`. */
:root .ak-card--pad { padding: var(--space-6); }
:root .ak-card--flat { border-color: var(--color-border-subtle); box-shadow: none; }
:root .ak-card--raised { box-shadow: var(--elevation-1); }
:root .ak-card--interactive {
  cursor: pointer;
  transition: box-shadow var(--dur-fast) var(--ease-standard),
              border-color var(--dur-fast) var(--ease-standard);
}
@media (hover: hover) {
  :root .ak-card--interactive:hover{ box-shadow: var(--elevation-2); border-color: var(--color-border); }
}
:root .ak-card--interactive:focus-visible{ outline: 2px solid var(--color-primary); outline-offset: 2px; }

:root .ak-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-block-end: var(--space-4);
}
:root .ak-card__title { font-size: var(--text-h4); font-weight: var(--fw-semibold); color: var(--color-text-primary); }
.ak-card__body > * + * { margin-block-start: var(--space-3); }
:root .ak-card__footer {
  margin-block-start: var(--space-5);
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--color-border-subtle);
  display: flex;
  gap: var(--space-2);
}

/* mobile: tighter card padding */
@media (max-width: 480px) {
  :root .ak-card--pad { padding: var(--space-4); }
  :root .ak-card { border-radius: var(--radius-md); }
}

/* bordered panel — a section that needs definition without elevation */
:root .ak-panel {
  background: var(--color-surface);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}

/* ============================================================
   PAGE HEADER  — Contract §21
   ============================================================ */
.ak-page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-block-end: var(--space-8);
}
.ak-page-header__text { min-width: 0; }
.ak-page-header__title {
  font-size: var(--text-h1);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
  color: var(--color-text-primary);
}
.ak-page-header__desc {
  margin-block-start: var(--space-2);
  font-size: var(--text-body);
  color: var(--color-text-secondary);
  max-width: 60ch;
}
.ak-page-header__actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
@media (max-width: 768px) {
  .ak-page-header__title { font-size: var(--text-h2); }
  .ak-page-header__actions { width: 100%; }
}

/* ============================================================
   KPI / STAT  — Contract §12 (KPI). Restrained, not "cards everywhere".
   ============================================================ */
.ak-kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-4);
  margin-block-end: var(--space-8);
}
.ak-kpi {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-5);
  background: var(--color-surface-elevated);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-lg);
}
.ak-kpi__label {
  font-size: var(--text-body-sm);
  color: var(--color-text-secondary);
}
.ak-kpi__value {
  font-size: var(--text-h1);
  font-weight: var(--fw-bold);
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
}
.ak-kpi__trend { font-size: var(--text-caption); display: inline-flex; align-items: center; gap: var(--space-1); }
.ak-kpi__trend--up { color: var(--color-success); }
.ak-kpi__trend--down { color: var(--color-error); }

/* ── src/components/04-overlay.css ─────────────────────────────────── */
/* ============================================================
   OVERLAY  (.ak-overlay)  — Contract §16
   One primitive → Dialog / Drawer / BottomSheet / Popover.
   Behaviour (focus trap, scroll lock, Esc) is in js/utils/overlay.js.
   Open/close is class-driven: .is-open on the root.

   .ak-overlay--compat  — the existing app modals keep their own DOM,
   show/hide and animation (showModal()/closeModal(), createElement /
   remove, .active). They do NOT carry the .ak-overlay base class, so the
   legacy stylesheet fully owns positioning and visibility; --compat only
   layers the premium look onto panel / header / body / footer via the
   .ak-overlay__* children. Behaviour comes from Overlay.enhance().
   ============================================================ */

:root .ak-overlay--compat .ak-overlay__panel {
  position: relative;
  display: block;
  max-block-size: none;
  overflow: visible;
  background: var(--color-surface-elevated);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-xl);
  box-shadow: var(--elevation-4);
}
:root .ak-overlay--compat .ak-overlay__header {
  padding: var(--space-5) var(--space-6);
  border-block-end: 1px solid var(--color-border-subtle);
}
:root .ak-overlay--compat .ak-overlay__body { padding: var(--space-6); overflow: auto; }
:root .ak-overlay--compat .ak-overlay__footer {
  padding: var(--space-4) var(--space-6);
  border-block-start: 1px solid var(--color-border-subtle);
  display: flex; gap: var(--space-2); justify-content: flex-end;
}
/* the backdrop / dim is the legacy modal container itself */
:root .ak-overlay--compat.modal-backdrop,
:root .ak-overlay--compat.modal-overlay,
:root .ak-overlay--compat.admin-modal,
:root .ak-overlay--compat.multiselect-drawer-overlay {
  background: var(--color-overlay);
}
/* drawer-style compat modals: flush inline edge */
:root .ak-overlay--compat.project-chat-modal .ak-overlay__panel,
:root .ak-overlay--compat.multiselect-drawer .ak-overlay__panel { border-radius: 0; }
/* mobile: dialog panels become top-rounded full-width sheets */
@media (max-width: 640px) {
  :root .ak-overlay--compat .ak-overlay__panel {
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    max-inline-size: 100%;
  }
}
:root .ak-overlay--compat .modal-close,
:root .ak-overlay--compat .close-modal,
:root .ak-overlay--compat .admin-modal-close,
:root .ak-overlay--compat .admin-modal-close-btn {
  color: var(--color-text-secondary);
  border-radius: var(--radius-md);
}
:root .ak-overlay--compat .modal-close:hover,
:root .ak-overlay--compat .admin-modal-close:hover {
  background: var(--color-primary-subtle);
  color: var(--color-text-primary);
}

:root .ak-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  visibility: hidden;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-standard),
              visibility 0s linear var(--dur-base);
}
:root .ak-overlay.is-open{
  visibility: visible;
  opacity: 1;
  transition: opacity var(--dur-slow) var(--ease-decelerate);
}

:root .ak-overlay__backdrop {
  position: absolute;
  inset: 0;
  background: var(--color-overlay);
  z-index: var(--z-modal-backdrop);
}

:root .ak-overlay__panel {
  position: relative;
  z-index: var(--z-modal);
  background: var(--color-surface-elevated);
  color: var(--color-text-primary);
  box-shadow: var(--elevation-4);
  border: 1px solid var(--color-border-subtle);
  display: flex;
  flex-direction: column;
  max-block-size: calc(100dvh - 2 * var(--space-8));
  overflow: hidden;
  transition: transform var(--dur-slow) var(--ease-decelerate);
}
:root .ak-overlay:not(.is-open) .ak-overlay__panel{ transition-duration: var(--dur-base); transition-timing-function: var(--ease-accelerate); }

:root .ak-overlay__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border-block-end: 1px solid var(--color-border-subtle);
}
:root .ak-overlay__title { font-size: var(--text-h4); font-weight: var(--fw-semibold); }
:root .ak-overlay__body { padding: var(--space-6); overflow: auto; flex: 1 1 auto; }
:root .ak-overlay__footer {
  display: flex; gap: var(--space-2); justify-content: flex-end;
  padding: var(--space-4) var(--space-6);
  border-block-start: 1px solid var(--color-border-subtle);
}

/* ── Dialog (default): centred ── */
:root .ak-overlay--dialog { place-items: center; padding: var(--space-8); }
.ak-overlay--dialog .ak-overlay__panel {
  inline-size: min(560px, 100%);
  border-radius: var(--radius-xl);
  transform: translateY(8px) scale(0.98);
}
:root .ak-overlay--dialog.is-open .ak-overlay__panel{ transform: none; }
:root .ak-overlay--dialog.ak-overlay--sm .ak-overlay__panel{ inline-size: min(400px, 100%); }
:root .ak-overlay--dialog.ak-overlay--lg .ak-overlay__panel{ inline-size: min(820px, 100%); }

/* ── Drawer: edge (inline-end for RTL) ── */
:root .ak-overlay--drawer { justify-items: end; }
.ak-overlay--drawer .ak-overlay__panel {
  block-size: 100dvh;
  max-block-size: 100dvh;
  inline-size: min(420px, 100%);
  border-radius: 0;
  transform: translateX(100%);
}
[dir="rtl"] .ak-overlay--drawer .ak-overlay__panel { transform: translateX(-100%); }
:root .ak-overlay--drawer.is-open .ak-overlay__panel{ transform: none; }

/* ── Bottom sheet ── */
:root .ak-overlay--sheet { align-items: end; }
.ak-overlay--sheet .ak-overlay__panel {
  inline-size: 100%;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  max-block-size: 88dvh;
  transform: translateY(100%);
  padding-block-end: env(safe-area-inset-bottom);
}
:root .ak-overlay--sheet.is-open .ak-overlay__panel{ transform: none; }
.ak-overlay--sheet .ak-overlay__panel::before {
  content: "";
  inline-size: 36px; block-size: 4px;
  border-radius: var(--radius-full);
  background: var(--color-border-strong);
  align-self: center;
  margin-block: var(--space-2);
}

/* ── Responsive: dialog → bottom sheet on phones ── */
@media (max-width: 640px) {
  :root .ak-overlay--dialog.ak-overlay--responsive{ align-items: end; padding: 0; }
  :root .ak-overlay--dialog.ak-overlay--responsive .ak-overlay__panel{
    inline-size: 100%;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    max-block-size: 88dvh;
    transform: translateY(100%);
  }
  :root .ak-overlay--dialog.ak-overlay--responsive.is-open .ak-overlay__panel{ transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  :root .ak-overlay,
  :root .ak-overlay__panel { transition-duration: 1ms !important; }
  :root .ak-overlay__panel { transform: none !important; }
}

/* ── Popover (anchored, not full-screen) ── */
:root .ak-popover {
  position: absolute;
  z-index: var(--z-popover);
  min-inline-size: 180px;
  background: var(--color-surface-elevated);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-md);
  box-shadow: var(--elevation-2);
  padding: var(--space-2);
}
:root .ak-popover:not(.is-open){ display: none; }
:root .ak-popover__item {
  display: flex; align-items: center; gap: var(--space-2);
  inline-size: 100%;
  padding: var(--space-2) var(--space-3);
  border: 0; background: transparent;
  border-radius: var(--radius-sm);
  font: inherit; color: var(--color-text-primary);
  text-align: start; cursor: pointer;
}
:root .ak-popover__item:hover{ background: var(--color-primary-subtle); }
:root .ak-popover__item:focus-visible{ outline: 2px solid var(--color-primary); outline-offset: -2px; }
:root .ak-popover__item--danger { color: var(--color-error); }

/* ── src/components/05-feedback.css ─────────────────────────────────── */
/* ============================================================
   FEEDBACK  — Badge · Alert · EmptyState · ErrorState · Loading
   Contract §12 / §19. Status never relies on colour alone.
   ============================================================ */

/* ── Badge ──
   Single shared recipe for every status/role/service pill in the project
   (admin + user) — Amir's explicit direction after seeing the first pass:
   not "the same rainbow of tinted pills, just consistent now" but an
   actually calmer, standard look. Every badge is now the SAME neutral
   pill (background/border/text never change), and status/role is carried
   entirely by a small coloured dot — nothing else changes colour. Text
   stays the normal muted colour on every single badge, on purpose.
   Previously each surface (admin users table, ticket badges, order/
   project status, role tags, service-type chips, the user-side status/
   priority badges…) had its own hand-rolled block with hardcoded hex
   colours, no two of them quite agreeing on the same status — e.g.
   "pending" was gold in one table and orange in another, and a couple of
   real statuses (ticket priority "important", project "escrowed"/"open")
   had no rule at all and rendered as bare text. This block is now the one
   place that owns the visual recipe and the status→colour mapping; every
   legacy class name below is kept so no markup/JS had to change, it's
   aliased onto the same rules instead. */
:where(
  .ak-badge, .admin-status-badge, .status-badge, .priority-badge,
  .admin-ticket-status-badge, .admin-ticket-priority-badge, .admin-bid-status,
  .role-badge, .service-type-badge, .admin-user-badge,
  .project-status, .bid-status
) {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: var(--radius-full);
  font-size: var(--text-caption);
  font-weight: var(--fw-semibold);
  line-height: 1.6;
  white-space: nowrap;
  background: var(--color-surface);
  color: var(--color-text-secondary);
  border: 1px solid var(--color-border-subtle);
  --_dot: var(--color-text-muted); /* neutral fallback for any unmapped value */
}
/* Contract §12/§19: status never relies on colour alone. Reads its colour
   from --_dot (set per status/role/service group below), not currentColor
   — the pill's own text stays the same neutral shade everywhere, only
   this dot carries the semantic colour. */
:where(
  .ak-badge, .admin-status-badge, .status-badge, .priority-badge,
  .admin-ticket-status-badge, .admin-ticket-priority-badge, .admin-bid-status,
  .role-badge, .service-type-badge, .admin-user-badge,
  .project-status, .bid-status
)::before {
  content: '';
  inline-size: 6px;
  block-size: 6px;
  border-radius: 50%;
  background: var(--_dot);
  flex: 0 0 auto;
}

/* ── Shared 7-hue semantic palette (dot colour only) ──
   Every badge family in the project (old class names kept on purpose —
   see comment above) maps onto exactly these 7 tokens. Never a raw hex,
   never the brand accent (reserved for buttons/links/focus — a "normal"
   ticket priority badge in brand yellow used to read as special/branded
   instead of just another state). */
.ak-badge--success,
.admin-status-badge.success, .admin-status-badge.active,
.admin-status-badge.status-active, .admin-status-badge.status-published,
.admin-status-badge.status-completed, .admin-status-badge.status-open,
.admin-status-badge.paid, .admin-status-badge.open,
.admin-status-badge.completed, .admin-status-badge.تکمیل‌شده,
.admin-status-badge.در-حال-اجرا,
.status-badge.status-active, .status-badge.status-published,
.status-badge.status-completed, .status-badge.status-open,
.status-badge.status-escrowed, .status-badge.status-verified,
.status-badge.completed,
.project-status.status-open, .project-status.status-completed,
.project-status.status-accepted, .project-status.status-active,
.project-status.status-published, .project-status.status-verified,
.bid-status.status-accepted, .bid-status.status-completed,
.admin-ticket-status-badge.ticket-status-open,
.admin-bid-status.status-accepted,
.role-employer, .admin-user-badge.role-employer,
.service-materials
{ --_dot: var(--color-success); }

.ak-badge--warning,
.admin-status-badge.warning, .admin-status-badge.pending,
.admin-status-badge.unverified, .admin-status-badge.status-pending,
.admin-status-badge.status-draft, .admin-status-badge.edit_requested,
.admin-status-badge.waiting, .admin-status-badge.reupload_required,
.admin-status-badge.در-حال-بررسی, .admin-status-badge.در-انتظار-پیمانکار,
.admin-status-badge.در-انتظار-شرکت-بیمه, .admin-status-badge.معلق,
.status-badge.status-pending, .status-badge.status-draft,
.status-badge.pending, .status-badge.edit_requested,
.project-status.status-pending, .project-status.status-draft,
.project-status.status-suspended, .project-status.status-on-hold,
.project-status.status-waiting,
.bid-status.status-pending,
.priority-badge.priority-important, .priority-badge.priority-warning,
.admin-ticket-priority-badge.priority-important,
.admin-ticket-status-badge.ticket-status-in-progress,
.admin-bid-status.status-pending,
.service-excavation
{ --_dot: var(--color-warning); }

.ak-badge--error,
.admin-status-badge.danger, .admin-status-badge.suspended,
.admin-status-badge.rejected, .admin-status-badge.status-canceled,
.admin-status-badge.status-closed, .admin-status-badge.canceled,
.admin-status-badge.لغوشده, .admin-status-badge.closed,
.status-badge.status-canceled, .status-badge.status-cancelled,
.status-badge.canceled, .status-badge.cancelled, .status-badge.rejected,
.status-badge.status-suspended,
.project-status.status-canceled, .project-status.status-cancelled,
.project-status.status-rejected, .project-status.status-closed,
.bid-status.status-rejected, .bid-status.status-canceled,
.priority-badge.priority-urgent, .priority-badge.priority-error,
.admin-ticket-priority-badge.priority-urgent,
.admin-ticket-status-badge.ticket-status-closed,
.admin-bid-status.status-rejected,
.service-demolition
{ --_dot: var(--color-error); }

.ak-badge--info,
.admin-status-badge.info, .admin-status-badge.status-in-progress,
.admin-status-badge.in-progress, .admin-status-badge.replied,
.status-badge.status-in-progress, .status-badge.status-connected,
.status-badge.in-progress, .status-badge.connected,
.project-status.status-in-progress, .project-status.status-escrowed,
.bid-status.status-in-progress,
.admin-ticket-status-badge.ticket-status-replied,
.role-contractor, .admin-user-badge.role-contractor,
.service-equipment
{ --_dot: var(--color-info); }

.admin-status-badge.purple, .admin-status-badge.در-انتظار-تایید-کارفرما,
.admin-status-badge.status-contract-signed,
.status-badge.purple, .status-badge.status-contract-signed,
.project-status.status-contract-signed,
.bid-status.status-contract-signed,
.role-supplier, .admin-user-badge.role-supplier,
.service-stabilization
{ --_dot: var(--color-purple); }

/* role-admin gets its own hue, but not gold/yellow — that's a near-miss
   for the brand accent itself (#f1c40f vs. #FFC107), which is exactly the
   "reads as special/branded" confusion araka-architect's badge rule warns
   about. Violet is unused elsewhere in this palette and reads as
   "administrative" without borrowing the brand colour. */
.admin-status-badge.violet, .role-admin, .admin-user-badge.role-admin
{ --_dot: var(--color-violet); }

.admin-status-badge.secondary, .admin-status-badge.deactivated,
.admin-status-badge.status-inactive, .admin-status-badge.status-suspended,
.status-badge.status-inactive, .status-badge.secondary,
.priority-badge.priority-normal, .priority-badge.priority-low,
.admin-ticket-priority-badge.priority-normal,
.role-default, .admin-user-badge.role-default,
.service-default
{ --_dot: var(--color-muted); }

.ak-badge--count {
  min-inline-size: 18px; block-size: 18px; padding: 0 4px;
  justify-content: center;
  background: var(--color-primary); color: var(--color-text-on-primary);
  border-color: transparent;
  font-variant-numeric: tabular-nums;
}
.ak-badge--count::before { content: none; }

/* ── Inline Alert ── */
.ak-alert {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border-inline-start: 3px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--text-body-sm);
  line-height: var(--lh-snug);
}
.ak-alert__icon { flex: 0 0 auto; color: var(--color-text-secondary); }
.ak-alert--success { border-inline-start-color: var(--color-success); }
.ak-alert--success .ak-alert__icon { color: var(--color-success); }
.ak-alert--warning { border-inline-start-color: var(--color-warning); }
.ak-alert--warning .ak-alert__icon { color: var(--color-warning); }
.ak-alert--error { border-inline-start-color: var(--color-error); }
.ak-alert--error .ak-alert__icon { color: var(--color-error); }
.ak-alert--info { border-inline-start-color: var(--color-info); }
.ak-alert--info .ak-alert__icon { color: var(--color-info); }

/* ── Empty / Error state (Contract §19: every data module needs these) ── */
.ak-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
  padding: var(--space-10) var(--space-6);
  color: var(--color-text-secondary);
}
.ak-state__icon {
  font-size: 32px;
  color: var(--color-text-muted);
}
.ak-state__title {
  font-size: var(--text-h4);
  font-weight: var(--fw-semibold);
  color: var(--color-text-primary);
}
.ak-state__desc { font-size: var(--text-body-sm); max-inline-size: 42ch; }
.ak-state__actions { margin-block-start: var(--space-2); display: flex; gap: var(--space-2); justify-content: center; }
.ak-state--error .ak-state__icon { color: var(--color-error); }
.ak-state--empty .ak-state__icon { color: var(--color-text-muted); }
.ak-state--loading { gap: var(--space-3); }
.ak-state--loading .ak-state__icon { color: var(--color-primary); }

/* ── Loading ── */
.ak-spinner {
  inline-size: 20px;
  block-size: 20px;
  border: 2px solid var(--color-border);
  border-block-start-color: var(--color-primary);
  border-radius: var(--radius-full);
  animation: ak-spin 0.7s linear infinite;
}
.ak-spinner--lg { inline-size: 32px; block-size: 32px; border-width: 3px; }
.ak-loading-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-8);
  color: var(--color-text-secondary);
  font-size: var(--text-body-sm);
}
@media (prefers-reduced-motion: reduce) {
  .ak-spinner { animation-duration: 1.4s; }
}

/* ── src/components/06-shell.css ─────────────────────────────────── */
/* ============================================================
   APP SHELL  (.ak-shell)  — Contract §18
   Shared structure for User + Admin. Only nav items / branding differ.
   Desktop: Sidebar + Main.  Mobile: BottomNav + Drawer.

   Layout is FLEX-based (row, RTL-aware) so it is compatible as an
   additive class on the existing `.dashboard-container` /
   `.admin-dashboard-container` flex shells — the `.ak-shell*`
   classes are the semantic / React contract over the same layout
   the app already uses. `.ak-shell__*` set only hooks + minor
   sizing, never a conflicting `display`.
   ============================================================ */

.ak-shell {
  display: flex;
  min-block-size: 100dvh;
  background: var(--color-bg);
}
/* semantic hooks only — the existing sidebar/main/bottom-nav CSS owns
   display + width; these just guarantee correct flex-child behaviour. */
.ak-shell__sidebar { flex: 0 0 auto; }
.ak-shell__main { flex: 1 1 auto; min-inline-size: 0; }
.ak-shell__bottomnav { flex: 0 0 auto; }

/* ── Header ── */
.ak-appbar {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-header-sticky);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: 56px;
  padding-inline: var(--space-page-inline);
  background: var(--color-header);
  border-block-end: 1px solid var(--color-border-subtle);
}
.ak-appbar__spacer { flex: 1 1 auto; }
.ak-appbar__title { font-size: var(--text-h4); font-weight: var(--fw-semibold); }

/* ── Sidebar / NavRail ── */
.ak-sidebar {
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4) var(--space-3);
  background: var(--color-surface-elevated);
  border-inline-end: 1px solid var(--color-border-subtle);
  overflow-y: auto;
}
.ak-sidebar__brand { padding: var(--space-3); margin-block-end: var(--space-4); }

/* ── Nav item (shared by sidebar, drawer) ── */
.ak-nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: 44px;
  padding-inline: var(--space-3);
  border-radius: var(--radius-md);
  color: var(--color-text-secondary);
  font-size: var(--text-body-sm);
  font-weight: var(--fw-medium);
  text-decoration: none;
  cursor: pointer;
  position: relative;
  transition: background-color var(--dur-fast) var(--ease-standard), color var(--dur-fast);
}
.ak-nav-item:hover { background: var(--color-primary-subtle); color: var(--color-text-primary); }
.ak-nav-item:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }
.ak-nav-item[aria-current="page"],
.ak-nav-item.is-active {
  background: var(--color-primary-subtle);
  color: var(--color-text-primary);
  font-weight: var(--fw-semibold);
}
.ak-nav-item[aria-current="page"]::before,
.ak-nav-item.is-active::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block: 8px;
  inline-size: 3px;
  border-radius: var(--radius-full);
  background: var(--color-primary);
}
.ak-nav-item > .ak-icon, .ak-nav-item > i, .ak-nav-item > svg { flex: 0 0 auto; width: var(--icon-md); }

/* ── Bottom navigation (mobile, both roles) ── */
.ak-bottomnav {
  position: sticky;
  inset-block-end: 0;
  z-index: var(--z-header-sticky);
  display: flex;
  background: var(--color-surface-elevated);
  border-block-start: 1px solid var(--color-border-subtle);
  padding-block-end: env(safe-area-inset-bottom);
}
.ak-bottomnav__item {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-block-size: 52px;
  padding-block: var(--space-1);
  border: 0;
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--text-caption);
  font-weight: var(--fw-medium);
  text-decoration: none;
  cursor: pointer;
}
.ak-bottomnav__item > i, .ak-bottomnav__item > svg { font-size: var(--icon-md); }
.ak-bottomnav__item[aria-current="page"],
.ak-bottomnav__item.is-active { color: var(--color-primary-ink); }
.ak-bottomnav__item:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -3px; }

/* ── Drawer nav (mobile "more") uses .ak-overlay--drawer for the shell ── */
.ak-drawer-nav { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-3); }

/* ============================================================
   TABS  — Contract §12
   ============================================================ */
.ak-tabs {
  display: flex;
  gap: var(--space-1);
  border-block-end: 1px solid var(--color-border-subtle);
  overflow-x: auto;
  scrollbar-width: none;
}
.ak-tabs::-webkit-scrollbar { display: none; }
.ak-tab {
  flex: 0 0 auto;
  min-block-size: 40px;
  padding-inline: var(--space-4);
  border: 0;
  background: transparent;
  color: var(--color-text-secondary);
  font: inherit;
  font-size: var(--text-body-sm);
  font-weight: var(--fw-medium);
  cursor: pointer;
  position: relative;
  white-space: nowrap;
}
.ak-tab:hover { color: var(--color-text-primary); }
.ak-tab:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }
.ak-tab[aria-selected="true"], .ak-tab.is-active {
  color: var(--color-text-primary);
  font-weight: var(--fw-semibold);
}
.ak-tab[aria-selected="true"]::after, .ak-tab.is-active::after {
  content: "";
  position: absolute;
  inset-inline: var(--space-3);
  inset-block-end: -1px;
  block-size: 2px;
  background: var(--color-primary);
  border-radius: var(--radius-full);
}

/* ============================================================
   DATA TABLE  — Contract §17 (desktop table; feature code owns columns)
   ============================================================ */
.ak-table-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-block-end: var(--space-4);
}
.ak-table-toolbar__spacer { flex: 1 1 auto; }
.ak-table-wrap {
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.ak-table-scroll { overflow-x: auto; }
.ak-table {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: var(--text-body-sm);
}
.ak-table th, .ak-table td {
  padding: var(--space-3) var(--space-4);
  text-align: start;
  border-block-end: 1px solid var(--color-border-subtle);
}
.ak-table th {
  background: var(--color-surface);
  font-weight: var(--fw-medium);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.ak-table tbody tr:last-child td { border-block-end: 0; }
.ak-table tbody tr:hover { background: var(--color-primary-subtle); }
.ak-table td.ak-num { font-variant-numeric: tabular-nums; text-align: end; }

/* mobile: caller adds .ak-table--cards to render rows as stacked cards.
   Previously each row only got a bottom hairline — no background/shadow of
   its own — so next to its (often same-tone) container it read as one flat
   list, not distinct cards despite the class name. Every row is now a real
   standalone card (background + border + shadow + radius + gap between
   rows), so it stays visually distinct regardless of whatever surface it's
   placed on. */
@media (max-width: 768px) {
  .ak-table--cards thead { display: none; }
  .ak-table--cards tr {
    display: grid;
    gap: var(--space-1);
    padding: var(--space-4);
    margin-block-end: var(--space-3);
    background: var(--color-surface-elevated);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    box-shadow: var(--elevation-1);
  }
  .ak-table--cards tr:last-child { margin-block-end: 0; }
  .ak-table--cards td { border: 0; padding: 0; display: flex; justify-content: space-between; gap: var(--space-3); }
  .ak-table--cards td::before {
    content: attr(data-label);
    color: var(--color-text-muted);
    font-size: var(--text-caption);
  }
}

/* ── src/components/07-navigation.css ─────────────────────────────────── */
/* ============================================================
   NAVIGATION LAYER — Contract §18
   Styles the real app nav classes (.header/.sidebar/.bottom-nav/.tab-btn/
   .nav-item …) + the .ak-nav-item / .ak-tab primitives. These container
   classes cannot take an additive .ak-* class (layout), so this is the
   canonical nav styling, not a transition shim.
   Aligns the existing user + admin header / sidebar / bottom-nav
   to one premium navigation language (Contract §18). Structure
   is unchanged; colour / border / elevation / active-state are
   unified so User and Admin read as one product.
   ============================================================ */

/* ── Header / AppBar ── */
:root .header,
:root .admin-header {
  background: var(--color-header);
  border-bottom: 1px solid var(--color-border-subtle);
  box-shadow: none;
}
[data-theme="dark"] .header,
[data-theme="dark"] .admin-header { border-bottom-color: var(--color-border-subtle); }

:root .header-btn,

:root .admin-header-btn,

:root .sidebar-toggle {
  color: var(--color-text-secondary);
  border-radius: var(--radius-md);
  transition: background-color var(--dur-fast) var(--ease-standard), color var(--dur-fast);
}
:root .header-btn:hover,
:root .sidebar-toggle:hover{ background: var(--color-primary-subtle); color: var(--color-text-primary); }
:root .header-btn:focus-visible,
:root .sidebar-toggle:focus-visible{ outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* ── Sidebar ── */
:root .sidebar,
:root .admin-sidebar {
  background: var(--color-surface-elevated);
  border-inline-end: 1px solid var(--color-border-subtle);
}
:root .admin-sidebar-header,
:root .sidebar-header { border-bottom: 1px solid var(--color-border-subtle); }
:root .admin-sidebar-footer,
:root .sidebar-footer { border-top: 1px solid var(--color-border-subtle); }

/* ── Nav items (user .nav-item + admin .admin-nav-link/.admin-nav-item) ──
   `transform` must be in this list too: admin-dashboard.css's own
   .admin-nav-link:hover moves the item with `transform: translateX(-5px)`,
   and this rule (higher specificity via :root, loads after) was the one
   actually controlling the transition — omitting transform here made the
   background/text fade smoothly while the position snapped instantly,
   reading as a harsh, un-animated hover despite both rules "having a
   transition". Duration bumped from --dur-fast (150ms) to --dur-base
   (250ms) so the combined color+position move reads as one deliberate,
   premium motion instead of a twitch. */
:root .nav-item,
:root .admin-nav-link,
:root .sidebar-nav-item {
  border-radius: var(--radius-md);
  color: var(--color-text-secondary);
  font-weight: var(--fw-medium);
  transition:
    background-color var(--dur-base) var(--ease-standard),
    color var(--dur-base) var(--ease-standard),
    transform var(--dur-base) var(--ease-standard);
}
:root .nav-item:hover,
:root .admin-nav-link:hover,
:root .sidebar-nav-item:hover{
  background: var(--color-primary-subtle);
  color: var(--color-text-primary);
}
:root .nav-item:focus-visible,
:root .admin-nav-link:focus-visible{ outline: 2px solid var(--color-primary); outline-offset: -2px; }
:root .nav-item.active,
:root .nav-item[aria-current="page"],
:root .admin-nav-item.active .admin-nav-link,
:root .admin-nav-link.active,
:root .admin-nav-link[aria-current="page"]{
  background: var(--color-primary-subtle);
  color: var(--color-text-primary);
  font-weight: var(--fw-semibold);
}
:root .nav-item.active .nav-icon,
:root .admin-nav-item.active .admin-nav-icon,
:root .admin-nav-link.active .admin-nav-icon{ color: var(--color-primary-ink); }

/* locked / disabled nav */
:root .nav-item-locked,
:root .nav-item.locked{ opacity: var(--opacity-disabled); cursor: not-allowed; }

/* ── Bottom nav (mobile) — user has it; admin gets the same treatment ── */
:root .bottom-nav {
  background: var(--color-surface-elevated);
  border-top: 1px solid var(--color-border-subtle);
  box-shadow: var(--elevation-3);
  padding-bottom: env(safe-area-inset-bottom);
}
:root .bottom-nav-item {
  color: var(--color-text-muted);
  font-weight: var(--fw-medium);
  transition: color var(--dur-fast) var(--ease-standard);
}
:root .bottom-nav-item.active,
:root .bottom-nav-item[aria-current="page"]{ color: var(--color-primary-ink); }
:root .bottom-nav-item:focus-visible{ outline: 2px solid var(--color-primary); outline-offset: -3px; }
:root .bottom-nav-drawer {
  background: var(--color-surface-elevated);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  box-shadow: var(--elevation-4);
  padding-bottom: env(safe-area-inset-bottom);
}
:root .bottom-nav-drawer-overlay { background: var(--color-overlay); }
:root .bottom-nav-drawer-handle {
  background: var(--color-border-strong);
  border-radius: var(--radius-full);
}
:root .bottom-nav-clock {
  color: var(--color-primary-ink);
  background: var(--color-primary-subtle);
  border-bottom: 1px solid var(--color-border-subtle);
}

/* ── Tabs (.tab-btn) ── */
:root .tab-btn {
  color: var(--color-text-secondary);
  font-weight: var(--fw-medium);
  border: 0;
  background: transparent;
  transition: color var(--dur-fast) var(--ease-standard);
}
:root .tab-btn:hover{ color: var(--color-text-primary); }
:root .tab-btn:focus-visible{ outline: 2px solid var(--color-primary); outline-offset: -2px; }
:root .tab-btn.active{
  color: var(--color-text-primary);
  font-weight: var(--fw-semibold);
  border-bottom: 2px solid var(--color-primary);
}

@media (prefers-reduced-motion: reduce) {
  :root .nav-item,
  :root .admin-nav-link,
  :root .bottom-nav-item,
  :root .tab-btn,
  :root .header-btn { transition: none; }
}

/* ── src/components/08-install-prompt.css ─────────────────────────────────── */
/* ============================================================
   INSTALL PROMPT  (.ak-install-prompt)
   Araka's own in-app "install the app" / "app status" nudge —
   injected by js/utils/pwa-install.js. Covers:
     • installable (real beforeinstallprompt) → CTA install
     • iOS Safari (no beforeinstallprompt)    → manual steps
     • already installed, up to date          → status confirmation
   Anchored bottom, logical inset so it flips correctly on this
   RTL-first site. Icon reuses the sitewide .theme-logo--light/dark
   swap (main.css) with the same logo-icon-*.webp pair boot.js uses,
   so it matches the current theme automatically — no JS branching.
   ============================================================ */

.ak-install-prompt {
  position: fixed;
  inset-inline: var(--space-4);
  inset-block-end: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
  z-index: 9990; /* below --z-toast, above nav/drawer */
  max-width: 420px;
  margin-inline-start: auto;
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-surface-elevated);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-xl);
  box-shadow: var(--elevation-4);
  font-family: var(--font-family-base);
  opacity: 0;
  transform: translateY(16px) scale(.98);
  transition:
    opacity var(--dur-slow) var(--ease-spring),
    transform var(--dur-slow) var(--ease-spring);
  pointer-events: none;
}
.ak-install-prompt.is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}
/* Sits above the mobile bottom nav / drawer trigger instead of on top of it */
body:has(.bottom-nav) .ak-install-prompt,
body:has(#adminBottomNav) .ak-install-prompt {
  inset-block-end: calc(76px + var(--space-2) + env(safe-area-inset-bottom, 0px));
}
@media (max-width: 560px) {
  .ak-install-prompt { max-width: none; margin-inline-start: 0; }
}

.ak-install-prompt__icon {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-lg);
  background: var(--color-surface-sunken);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.ak-install-prompt__icon img { width: 26px; height: 26px; object-fit: contain; }

.ak-install-prompt__body { flex: 1 1 auto; min-width: 0; }
.ak-install-prompt__title {
  margin: 0 0 2px;
  font-size: var(--text-body);
  font-weight: var(--fw-bold);
  color: var(--color-text-primary);
}
.ak-install-prompt__desc {
  margin: 0;
  font-size: var(--text-body-sm);
  color: var(--color-text-secondary);
  line-height: 1.6;
}
.ak-install-prompt__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-start: var(--space-3);
}
.ak-install-prompt__actions .ak-btn { flex: 0 0 auto; }

.ak-install-prompt__close {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  color: var(--color-text-muted);
  border-radius: var(--radius-full);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard);
}
@media (hover: hover) {
  .ak-install-prompt__close:hover { background: var(--color-surface-sunken); color: var(--color-text-primary); }
}
.ak-install-prompt__close svg { width: 16px; height: 16px; }

/* Status/confirmation variant ("already installed, up to date") — no
   persistent actions, auto-dismisses itself via JS after a few seconds. */
.ak-install-prompt--status .ak-install-prompt__icon {
  background: var(--color-primary-subtle);
}
.ak-install-prompt--status .ak-install-prompt__title { color: var(--color-text-primary); }
.ak-install-prompt--status .ak-install-prompt__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--color-success);
  color: #fff;
  margin-inline-end: 6px;
  flex: 0 0 auto;
}
.ak-install-prompt--status .ak-install-prompt__badge svg { width: 10px; height: 10px; }

@media (prefers-reduced-motion: reduce) {
  .ak-install-prompt { transition: opacity var(--dur-fast) linear; transform: none; }
}
