/* ASAS - component layer (Milestone F1)
 *
 * Depends on tokens.css + base.css. Load order:
 *   tokens.css -> base.css -> components.css
 *
 * This is the ONLY component styling system. Do not introduce a second one.
 * Every component below implements all nine states: hover, focus-visible,
 * active, selected, disabled, loading, empty, error, success.
 *
 * Logical properties only (see base.css).
 */

/* ======================================================== BUTTON ======= */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-3);
  block-size: var(--h-md);
  padding-inline: var(--s-5);
  border: var(--bw) solid transparent;
  /* Actions are pills (identity: button radius 999px); surfaces are square. */
  border-radius: var(--r-full);
  font-size: var(--t-body-size); line-height: 1; font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.btn:focus-visible { border-radius: var(--r-full); }
.btn:focus-visible { box-shadow: var(--focus-ring); }

.btn-xs { block-size: var(--h-xs); padding-inline: var(--s-3); font-size: var(--t-meta-size); }
.btn-sm { block-size: var(--h-sm); padding-inline: var(--s-4); font-size: var(--t-secondary-size); }
.btn-lg { block-size: var(--h-lg); padding-inline: var(--s-6); }

/* Primary is GOLD on the dark field (INK on the Bone field). Its hover is one
 * of the three places the identity allows a glow. One primary per view. */
.btn-primary { background: var(--action-bg); color: var(--action-fg); font-weight: 600; }
.btn-primary:hover { background: var(--action-bg-hover); box-shadow: var(--glow-primary); }
.btn-primary:active { background: var(--action-bg-active); }

.btn-secondary {
  background: var(--bg-surface); color: var(--text-primary);
  border-color: var(--border-input);
}
.btn-secondary:hover { background: var(--bg-hover); }
.btn-secondary:active { background: var(--bg-sunken); }

.btn-ghost { background: transparent; color: var(--text-secondary); }
.btn-ghost:hover { background: var(--bg-hover); color: var(--text-primary); }
.btn-ghost:active { background: var(--bg-sunken); }

/* A link styled as a button reads as a button: no underline in any container. */
a.btn { text-decoration: none; }
.btn-danger { background: var(--danger-6); color: var(--danger-fg); font-weight: 600; }
.btn-danger:hover { background: var(--danger-7); }
.btn-danger:active { background: var(--danger-7); }

.btn-link {
  background: none; color: var(--accent-6); block-size: auto;
  padding-inline: 0; font-weight: 400;
}
.btn-link:hover { color: var(--accent-7); text-decoration: underline; }

/* Icon-only. Requires aria-label + tooltip. FORBIDDEN for destructive actions -
 * those always carry a text label. */
.btn-icon { inline-size: var(--h-md); padding-inline: 0; }
.btn-icon.btn-sm { inline-size: var(--h-sm); }
.btn-icon.btn-xs { inline-size: var(--h-xs); }

.btn[disabled], .btn[aria-disabled="true"] {
  opacity: .45; cursor: not-allowed; pointer-events: none;
}

/* Loading keeps the button's width so the layout never jumps. */
.btn[data-loading="true"] { position: relative; color: transparent; pointer-events: none; }
.btn[data-loading="true"]::after {
  content: ""; position: absolute; inset-inline: var(--s-5);
  inset-block-end: var(--s-3); block-size: 2px; border-radius: var(--r-full);
  background: currentColor; opacity: .35;
  animation: indeterminate 1.1s var(--ease-out) infinite;
}
.btn-primary[data-loading="true"]::after,
.btn-danger[data-loading="true"]::after { background: var(--action-fg); }

@keyframes indeterminate {
  0%   { transform: scaleX(.15); transform-origin: 0 50%; }
  50%  { transform: scaleX(1);   transform-origin: 0 50%; }
  100% { transform: scaleX(.15); transform-origin: 100% 50%; }
}

/* ================================================ INPUT / SELECT ======= */

.field { display: grid; gap: var(--s-3); }
.field > .field-label {
  font-size: var(--t-label-size); line-height: var(--t-label-lh);
  font-weight: var(--t-label-w); color: var(--text-tertiary);
}
.field-hint { font-size: var(--t-meta-size); color: var(--text-tertiary); }
.field-error {
  display: flex; align-items: flex-start; gap: var(--s-2);
  font-size: var(--t-meta-size); line-height: var(--t-meta-lh);
  color: var(--danger-6);
}
.field-required { color: var(--danger-6); }

.input, .textarea, .select {
  inline-size: 100%;
  block-size: var(--h-md);
  padding-inline: var(--s-4);
  background: var(--bg-surface);
  color: var(--text-primary);
  /* --border-input is 3:1 because this border IS the control's affordance. */
  border: var(--bw) solid var(--border-input);
  border-radius: var(--r-sm);
  transition: border-color var(--dur-fast) var(--ease-out);
}
.textarea { block-size: auto; min-block-size: 72px; padding-block: var(--s-3); resize: vertical; }

.input:hover, .textarea:hover, .select:hover { border-color: var(--text-tertiary); }
.input:focus-visible, .textarea:focus-visible, .select:focus-visible {
  border-color: var(--accent-6); box-shadow: var(--focus-ring);
}
.input::placeholder, .textarea::placeholder { color: var(--text-disabled); }

.input[disabled], .textarea[disabled], .select[disabled] {
  background: var(--bg-sunken); color: var(--text-disabled);
  cursor: not-allowed; opacity: 1;
}

.input[aria-invalid="true"], .textarea[aria-invalid="true"], .select[aria-invalid="true"] {
  border-color: var(--danger-6);
}
.input[aria-invalid="true"]:focus-visible { box-shadow: 0 0 0 2px var(--bg-surface), 0 0 0 4px var(--danger-6); }

.input[data-state="success"] { border-color: var(--success-6); }

/* Native select, styled. Zero dependency, correct on mobile, correct in RTL. */
.select {
  appearance: none;
  padding-inline-end: var(--s-9);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238A93AE' stroke-width='1.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 var(--s-4) center;
}
[dir="rtl"] .select { background-position: left var(--s-4) center; }

.checkbox, .radio {
  inline-size: 16px; block-size: 16px; flex: none;
  accent-color: var(--accent-6); cursor: pointer;
  /* 16px drawn, 24px kept clear around it (WCAG 2.2, 2.5.8 target spacing). */
  margin: 4px;
}
.checkbox:focus-visible, .radio:focus-visible { box-shadow: var(--focus-ring); }

/* ======================================================== SEARCH ======= */

.search { position: relative; display: flex; align-items: center; }
.search > .search-icon {
  position: absolute; inset-inline-start: var(--s-4);
  color: var(--text-tertiary); pointer-events: none;
}
.search > .input { padding-inline-start: var(--s-9); }
.search > .search-clear {
  position: absolute; inset-inline-end: var(--s-2);
  color: var(--text-tertiary);
}
.search > .search-clear:hover { color: var(--text-primary); }
.search-sm > .input { block-size: var(--h-sm); }

/* ========================================================== CARD ======= */

/* Cards are defined by their border. No shadow, no nesting, no hover lift.
 * Square-cut, with the Monolith hairline: the top edge is a shade lighter, so
 * a panel reads as a bevel of dark glass rather than a flat box. */
.card {
  background: var(--bg-surface);
  border: var(--bw) solid var(--border-default);
  border-block-start-color: var(--border-bevel);
  border-radius: var(--r-md);
}
.card-header {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; /* on a phone the actions move under the title rather than off the screen */
  gap: var(--s-4);
  padding: var(--s-5) var(--s-6);
  border-block-end: var(--bw) solid var(--border-subtle);
}
.card-header > .row { flex-wrap: wrap; }
.card-header.is-banded { background: var(--bg-subtle); border-start-start-radius: var(--r-md); border-start-end-radius: var(--r-md); }
.card-body { padding: var(--s-6); }
.card-body.is-flush { padding: 0; }
.card-footer {
  padding: var(--s-4) var(--s-6);
  border-block-start: var(--bw) solid var(--border-subtle);
  background: var(--bg-subtle);
  border-end-start-radius: var(--r-md); border-end-end-radius: var(--r-md);
}

/* ========================================================= TABLE ======= */

.table-wrap { inline-size: 100%; overflow-x: auto; overscroll-behavior-x: contain; }
.table { inline-size: 100%; font-size: var(--t-cell-size); line-height: var(--t-cell-lh); }

.table thead th {
  position: sticky; inset-block-start: 0; z-index: 1;
  background: var(--bg-subtle);
  padding: var(--s-3) var(--s-4);
  text-align: start;
  font-size: var(--t-overline-size); line-height: var(--t-overline-lh);
  font-weight: var(--t-overline-w); letter-spacing: var(--t-overline-ls);
  text-transform: uppercase; color: var(--text-tertiary);
  border-block-end: var(--bw) solid var(--border-default);
  white-space: nowrap;
}
.table tbody td {
  padding: 0 var(--s-4);
  block-size: var(--row-default);
  border-block-end: var(--bw) solid var(--border-subtle);
  vertical-align: middle;
}
.table.is-compact tbody td { block-size: var(--row-compact); }
.table.is-comfortable tbody td { block-size: var(--row-comfortable); }

/* No zebra: hairlines carry the row rhythm without the visual noise. */
.table tbody tr:hover { background: var(--bg-hover); }
.table tbody tr[aria-selected="true"] {
  background: var(--bg-selected);
  box-shadow: inset 2px 0 0 0 var(--accent-6);
}
[dir="rtl"] .table tbody tr[aria-selected="true"] { box-shadow: inset -2px 0 0 0 var(--accent-6); }
.table tbody tr[aria-disabled="true"] { color: var(--text-disabled); }
.table tbody tr:focus-visible { box-shadow: var(--focus-ring); }

.table .num { text-align: end; font-variant-numeric: tabular-nums; }
.table .col-actions { inline-size: 1%; white-space: nowrap; text-align: end; }

/* Column priority drives responsive collapse deterministically rather than by
 * whatever happens to overflow. p1 always survives. */
@media (max-width: 1439px) { .table .p4 { display: none; } }
@media (max-width: 1119px) { .table .p3 { display: none; } }
@media (max-width: 767px)  { .table .p2 { display: none; } }

@media (max-width: 767px) {
  .table.is-sticky-first th:first-child,
  .table.is-sticky-first td:first-child {
    position: sticky; inset-inline-start: 0; background: var(--bg-surface);
  }
  .table.is-sticky-first thead th:first-child { background: var(--bg-subtle); }
}

/* ========================================================== LIST ======= */

.list { display: flex; flex-direction: column; }
.list-item {
  display: flex; align-items: flex-start; gap: var(--s-4);
  inline-size: 100%;
  padding: var(--s-4) var(--s-5);
  text-align: start;
  border-block-end: var(--bw) solid var(--border-subtle);
  transition: background-color var(--dur-fast) var(--ease-out);
}
.list-item:hover { background: var(--bg-hover); }
.list-item:active { background: var(--bg-sunken); }
.list-item[aria-selected="true"] {
  background: var(--bg-selected);
  box-shadow: inset 2px 0 0 0 var(--accent-6);
}
[dir="rtl"] .list-item[aria-selected="true"] { box-shadow: inset -2px 0 0 0 var(--accent-6); }
.list-item[aria-disabled="true"] { color: var(--text-disabled); pointer-events: none; }
.list-item:focus-visible { box-shadow: var(--focus-ring); }
/* Needs-attention rows carry a rule AND a chip - never colour alone. The rule
 * is a filament: the identity lets the one thing that needs a person glow. */
.list-item.is-attention { box-shadow: inset 2px 0 0 0 var(--warning-fill), inset 10px 0 14px -10px rgba(245, 197, 66, .4); }
[dir="rtl"] .list-item.is-attention { box-shadow: inset -2px 0 0 0 var(--warning-fill), inset -10px 0 14px -10px rgba(245, 197, 66, .4); }
[data-theme="light"] .list-item.is-attention { box-shadow: inset 2px 0 0 0 var(--warning-fill); }
[data-theme="light"][dir="rtl"] .list-item.is-attention { box-shadow: inset -2px 0 0 0 var(--warning-fill); }

/* ========================================================== TABS ======= */

.tabs {
  display: flex; align-items: center; gap: var(--s-6);
  border-block-end: var(--bw) solid var(--border-default);
  /* A tab strip is a single line that scrolls, never one that wraps or widens
   * the document. Without this the English settings strip forced 75px of
   * horizontal page scroll on a 320px phone. Note that `overflow-x: auto`
   * makes the used value of `overflow-y` `auto` too - it cannot stay
   * `visible` - so the selected-tab underline has to sit inside the padding
   * box rather than straddling the border. See `inset-block-end` below. */
  overflow-x: auto;
  overscroll-behavior-x: contain;
}
.tab {
  position: relative;
  flex: 0 0 auto;
  block-size: var(--h-md);
  padding-inline: var(--s-1);
  color: var(--text-secondary);
  font-size: var(--t-body-size); font-weight: 500;
  transition: color var(--dur-fast) var(--ease-out);
}
.tab:hover { color: var(--text-primary); }
.tab:focus-visible { box-shadow: var(--focus-ring); }
.tab[aria-selected="true"] { color: var(--text-primary); }
.tab[aria-selected="true"]::after {
  content: ""; position: absolute;
  /* Flush with the bottom of the strip's padding box, not -1px over the
   * container border: the strip is a scroll container and anything below the
   * padding box is clipped and adds a 1px vertical scroll. */
  inset-inline: 0; inset-block-end: 0;
  block-size: 2px; background: var(--accent-6);
}
.tab[aria-disabled="true"] { color: var(--text-disabled); pointer-events: none; }

/* ========================================= BADGE / STATUS INDICATOR ==== */

.badge {
  display: inline-flex; align-items: center; gap: var(--s-2);
  block-size: var(--h-xs);
  padding-inline: var(--s-4);
  border-radius: var(--r-full);
  border: var(--bw) solid transparent;
  font-size: var(--t-meta-size); line-height: 1; font-weight: 500;
  white-space: nowrap;
}
.badge-neutral { background: var(--bg-sunken); color: var(--text-secondary); border-color: var(--border-default); }
.badge-accent  { background: var(--accent-1);  color: var(--accent-6);  border-color: var(--accent-2); }
.badge-success { background: var(--success-1); color: var(--success-6); border-color: var(--success-2); }
.badge-warning { background: var(--warning-1); color: var(--warning-6); border-color: var(--warning-2); }
.badge-danger  { background: var(--danger-1);  color: var(--danger-6);  border-color: var(--danger-2); }
.badge-info    { background: var(--info-1);    color: var(--info-6);    border-color: var(--info-2); }

.badge-count {
  border-radius: var(--r-full); padding-inline: var(--s-3);
  font-variant-numeric: tabular-nums;
}

/* Status is ALWAYS dot + text. The dot alone is never sufficient:
 * SC 1.4.1 - colour must not be the only visual means of conveying meaning. */
.status { display: inline-flex; align-items: center; gap: var(--s-3); white-space: nowrap; }
.status-dot { inline-size: 6px; block-size: 6px; border-radius: var(--r-full); flex: none; }
.status-dot.is-ok      { background: var(--success-6); }
.status-dot.is-warn    { background: var(--warning-fill); }
.status-dot.is-error   { background: var(--danger-6); }
.status-dot.is-idle    { background: var(--neutral-fill); }
.status-dot.is-active  { background: var(--accent-6); }
.status-dot.is-info    { background: var(--info-6); }

/* ======================================================== DIALOG ======= */

.overlay {
  position: fixed; inset: 0; z-index: var(--z-dialog);
  background: var(--bg-overlay);
  display: grid; place-items: center;
  padding: var(--s-6);
  animation: fade var(--dur-base) var(--ease-out);
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* Dialogs are for CREATE and CONFIRM only. Detail and inspect use a drawer,
 * so that reading a record never costs you your place in a list. */
.dialog {
  inline-size: min(560px, 100%);
  max-block-size: calc(100vh - var(--s-12));
  display: flex; flex-direction: column;
  background: var(--bg-surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  animation: dialog-in var(--dur-base) var(--ease-out);
}
@keyframes dialog-in {
  from { opacity: 0; transform: scale(.98); }
  to   { opacity: 1; transform: none; }
}
.dialog-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); padding: var(--s-6);
  border-block-end: var(--bw) solid var(--border-subtle);
}
.dialog-body { padding: var(--s-6); overflow-y: auto; }
.dialog-footer {
  display: flex; align-items: center; justify-content: flex-end; gap: var(--s-4);
  padding: var(--s-5) var(--s-6);
  border-block-start: var(--bw) solid var(--border-subtle);
}

/* ======================================================== DRAWER ======= */

.drawer {
  position: fixed; z-index: var(--z-drawer);
  inset-block: 0; inset-inline-end: 0;
  inline-size: min(var(--drawer-w), 100%);
  display: flex; flex-direction: column;
  background: var(--bg-surface);
  border-inline-start: var(--bw) solid var(--border-default);
  box-shadow: var(--shadow-2);
  animation: drawer-in var(--dur-slow) var(--ease-out);
}
@keyframes drawer-in {
  from { transform: translateX(16px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
[dir="rtl"] .drawer { animation-name: drawer-in-rtl; }
@keyframes drawer-in-rtl {
  from { transform: translateX(-16px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
.drawer-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--s-4); padding: var(--s-5) var(--s-6);
  border-block-end: var(--bw) solid var(--border-subtle);
}
.drawer-body { flex: 1 1 auto; overflow-y: auto; padding: var(--s-6); }
.drawer-footer {
  display: flex; align-items: center; justify-content: flex-end; gap: var(--s-4);
  padding: var(--s-5) var(--s-6);
  border-block-start: var(--bw) solid var(--border-subtle);
}

/* ================================================== BOTTOM SHEET ======= */

.sheet {
  position: fixed; z-index: var(--z-drawer);
  inset-inline: 0; inset-block-end: 0;
  max-block-size: 88vh;
  display: flex; flex-direction: column;
  background: var(--bg-surface);
  border-start-start-radius: var(--r-lg);
  border-start-end-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  animation: sheet-in var(--dur-slow) var(--ease-out);
}
@keyframes sheet-in {
  from { transform: translateY(12px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
.sheet-grabber {
  inline-size: 36px; block-size: 4px; border-radius: var(--r-full);
  background: var(--border-strong); margin: var(--s-3) auto;
}

/* Drawers become sheets on phones; dialogs go full-screen below 640. */
@media (max-width: 767px) {
  .drawer {
    inset-block-start: auto; inset-inline: 0;
    inline-size: 100%; max-block-size: 88vh;
    border-inline-start: 0;
    border-start-start-radius: var(--r-lg); border-start-end-radius: var(--r-lg);
    animation-name: sheet-in;
  }
}
@media (max-width: 639px) {
  .overlay { padding: 0; }
  .dialog {
    inline-size: 100%; max-block-size: 100vh; block-size: 100%;
    border-radius: 0;
  }
}

/* ======================================================= TOOLTIP ======= */

.tooltip {
  position: fixed; z-index: var(--z-tooltip);
  max-inline-size: 260px;
  padding: var(--s-2) var(--s-3);
  background: var(--bg-inverse); color: var(--text-inverse);
  border-radius: var(--r-xs);
  font-size: var(--t-meta-size); line-height: var(--t-meta-lh);
  pointer-events: none;
  animation: fade var(--dur-fast) var(--ease-out);
}

/* ========================================================= TOAST ======= */

.toast-host {
  position: fixed; z-index: var(--z-toast);
  inset-block-end: var(--s-6); inset-inline-start: var(--s-6);
  display: flex; flex-direction: column; gap: var(--s-3);
  pointer-events: none;
}
.toast {
  display: flex; align-items: flex-start; gap: var(--s-4);
  inline-size: min(400px, calc(100vw - var(--s-12)));
  padding: var(--s-4) var(--s-5);
  background: var(--bg-surface);
  border: var(--bw) solid var(--border-default);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-2);
  pointer-events: auto;
  animation: toast-in var(--dur-base) var(--ease-out);
}
@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.toast.is-success { border-inline-start: 3px solid var(--success-6); }
.toast.is-warning { border-inline-start: 3px solid var(--warning-fill); }
.toast.is-error   { border-inline-start: 3px solid var(--danger-6); }
.toast.is-info    { border-inline-start: 3px solid var(--accent-6); }

/* ==================================================== FILTER BAR ======= */

.filterbar {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  background: var(--bg-surface);
  border-block-end: var(--bw) solid var(--border-subtle);
}
.segmented {
  display: inline-flex; padding: 2px;
  background: var(--bg-sunken);
  border: var(--bw) solid var(--border-subtle);
  /* A pill on one row; when a long filter set wraps it becomes a rounded
     panel rather than a stadium. */
  border-radius: 18px;
  /* Never wider than the column it sits in: unconstrained, the inbox filter
   * is 319px and pushes the document 23px wide on a 320px phone. It wraps to
   * a second row rather than scrolling or ellipsizing - a scroll container
   * would clip the 4px focus ring, and shrinking the segments truncates
   * "Mine" and "All" to "M..." and "A...", which say nothing. */
  flex-wrap: wrap;
  max-inline-size: 100%;
}
.segment {
  block-size: var(--h-sm); padding-inline: var(--s-5);
  border-radius: var(--r-full);
  font-size: var(--t-secondary-size); font-weight: 500;
  color: var(--text-secondary);
  white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.segment:hover { color: var(--text-primary); }
.segment:focus-visible { box-shadow: var(--focus-ring); }
.segment[aria-selected="true"] {
  background: var(--bg-selected); color: var(--text-primary);
  box-shadow: inset 0 0 0 var(--bw) var(--border-strong);
}
.segment[aria-disabled="true"] { color: var(--text-disabled); pointer-events: none; }

.chip {
  display: inline-flex; align-items: center; gap: var(--s-2);
  block-size: var(--h-sm); padding-inline: var(--s-3);
  background: var(--accent-1); color: var(--accent-6);
  border: var(--bw) solid var(--accent-2);
  border-radius: var(--r-full);
  font-size: var(--t-secondary-size);
}
.chip-remove { display: inline-flex; color: currentColor; opacity: .75; }
.chip-remove:hover { opacity: 1; }

/* ==================================================== PAGINATION ======= */

/* Release-1 stopgap: no endpoint accepts a cursor or offset, so we show the
 * true count we hold and a Load more. This upgrades to real cursor paging with no
 * visual change once the backend supports it. */
.pagination {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  border-block-start: var(--bw) solid var(--border-subtle);
}
.pagination-count {
  font-size: var(--t-secondary-size); color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}
/* Shown when the client-side cap is reached, so we never imply completeness. */
.pagination-capped { color: var(--warning-6); }

/* ======================================================== STATES ======= */

/* Loading: skeletons matched to real row geometry. Never a spinner in a list. */
.skeleton {
  background: var(--bg-sunken);
  border-radius: var(--r-xs);
  background-image: linear-gradient(90deg, transparent, rgba(255,255,255,.6), transparent);
  background-size: 200% 100%;
  background-repeat: no-repeat;
  animation: shimmer 1.4s var(--ease-out) infinite;
}
@keyframes shimmer {
  from { background-position: -100% 0; }
  to   { background-position: 200% 0; }
}
.skeleton-text { block-size: 12px; margin-block: var(--s-2); }
.skeleton-row  { block-size: var(--row-default); margin-block-end: var(--bw); }

/* Empty: must distinguish "nothing yet" from "nothing matches your filter". */
.empty {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--s-4);
  padding: var(--s-11) var(--s-6);
  text-align: center;
  color: var(--text-secondary);
}
.empty-icon { color: var(--text-disabled); }
.empty-title { font-size: var(--t-section-size); font-weight: var(--t-section-w); color: var(--text-primary); }
.empty-body { max-inline-size: 42ch; font-size: var(--t-secondary-size); }

/* Error: inline, specific, recoverable. Never a bare error code. */
.state-error {
  display: flex; align-items: flex-start; gap: var(--s-4);
  padding: var(--s-5);
  background: var(--danger-1);
  border: var(--bw) solid var(--danger-2);
  border-radius: var(--r-md);
  color: var(--text-primary);
}
.state-error .state-title { color: var(--danger-6); font-weight: var(--t-strong-w); }

.state-success {
  display: flex; align-items: flex-start; gap: var(--s-4);
  padding: var(--s-5);
  background: var(--success-1);
  border: var(--bw) solid var(--success-2);
  border-radius: var(--r-md);
}
.state-success .state-title { color: var(--success-6); font-weight: var(--t-strong-w); }

.notice {
  display: flex; align-items: flex-start; gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  background: var(--bg-subtle);
  border: var(--bw) solid var(--border-default);
  border-inline-start: 2px solid var(--info-6);
  border-radius: var(--r-md);
  font-size: var(--t-secondary-size);
  color: var(--text-secondary);
}
.notice-icon { color: var(--info-6); line-height: 0; margin-block-start: 1px; }
.notice-action { align-self: center; }
.notice-warning { background: var(--warning-1); border-color: var(--warning-2); border-inline-start-color: var(--warning-fill); color: var(--text-primary); }
.notice-warning .notice-icon { color: var(--warning-6); }
.notice-danger { background: var(--danger-1); border-color: var(--danger-2); border-inline-start-color: var(--danger-6); color: var(--text-primary); }
.notice-danger .notice-icon { color: var(--danger-6); }
.notice-success { background: var(--success-1); border-color: var(--success-2); border-inline-start-color: var(--success-6); }
.notice-success .notice-icon { color: var(--success-6); }

/* ========================================================= SHELL ======= */

.app-shell {
  display: grid;
  grid-template-columns: var(--nav-w) minmax(0, 1fr);
  min-block-size: 100vh;
  min-block-size: 100dvh;
}
.app-shell.is-rail { grid-template-columns: var(--nav-rail-w) minmax(0, 1fr); }

.app-nav {
  display: flex; flex-direction: column;
  background: var(--bg-inverse); color: var(--text-inverse-muted);
  position: sticky; inset-block-start: 0;
  block-size: 100vh; block-size: 100dvh;
  overflow-y: auto;
}
.app-brand {
  display: flex; align-items: center; gap: var(--s-4);
  block-size: var(--header-h); flex: none;
  padding-inline: var(--s-5);
  color: var(--text-inverse); font-weight: 600;
  font-family: var(--font-display);
  border-block-end: var(--bw) solid var(--border-subtle);
}
/* The product mark carries the brand hue; the tenant's own name beside it stays
 * plain inverse text, so the sidebar reads as "ASAS, for this business" rather
 * than tinting the tenant. --accent-3 is the sidebar-safe step of the ramp. */
.app-brand-mark { color: var(--accent-3); display: inline-flex; margin-inline: -11px -6px; }
.app-brand-text { display: flex; flex-direction: column; gap: 3px; min-inline-size: 0; }
.app-brand-name {
  font-family: var(--font-sans); font-weight: 400;
  font-size: var(--t-meta-size); line-height: var(--t-meta-lh);
  color: var(--text-inverse-subtle);
}
html[lang="ar"] .app-brand-name { font-family: var(--font-arabic); }

/* The name is always the wordmark: Alexandria, Latin capitals tracked +14%;
 * Arabic Bold, never tracked. Never "Asas", never a descriptor. */
.asas-wordmark { font-family: var(--font-display); line-height: 1; color: var(--text-inverse); }
.asas-wordmark-en { font-weight: 600; text-transform: uppercase; letter-spacing: .14em; font-size: 15px; }
.asas-wordmark-ar { font-weight: 700; letter-spacing: 0; font-size: 17px; }
.nav-group { padding: var(--s-4) var(--s-3); }
.nav-group + .nav-group { border-block-start: var(--bw) solid var(--border-subtle); }
.nav-directory { margin-inline:var(--s-3); border-block-start:var(--bw) solid var(--border-subtle); padding-block-start:var(--s-3); }
.nav-directory-summary { display:flex; align-items:center; gap:var(--s-4); min-block-size:var(--h-lg); padding-inline:var(--s-4); border-radius:var(--r-sm); color:var(--text-inverse-muted); cursor:pointer; list-style:none; font-size:var(--t-body-size); }
.nav-directory-summary::-webkit-details-marker { display:none; }
.nav-directory-summary:hover, .nav-directory[open] .nav-directory-summary { background:var(--bg-nav-active); color:var(--text-inverse); }
.nav-directory-summary:focus-visible { box-shadow:var(--focus-ring-inverse); }
.nav-directory-chevron { margin-inline-start:auto; transition:transform var(--dur-base) var(--ease-out); }
.nav-directory[open] .nav-directory-chevron { transform:rotate(180deg); }
.nav-directory .nav-group { padding-inline:0; }
.nav-directory .nav-group-label { padding-block-start:var(--s-4); }
.nav-group-label {
  padding: var(--s-2) var(--s-4) var(--s-3);
  font-size: var(--t-overline-size); font-weight: var(--t-overline-w);
  letter-spacing: var(--t-overline-ls); text-transform: uppercase;
  color: var(--text-inverse-subtle);
}
.nav-item {
  position: relative;
  display: flex; align-items: center; gap: var(--s-4);
  inline-size: 100%; block-size: var(--h-lg);
  padding-inline: var(--s-4);
  border-radius: var(--r-sm);
  color: var(--text-inverse-muted);
  font-size: var(--t-body-size); text-align: start;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.nav-item:hover { background: var(--bg-nav-active); color: var(--text-inverse); }
.nav-item[aria-current="page"] {
  background: var(--bg-nav-active); color: var(--text-inverse); font-weight: 500;
}
/* Where you are is lit: a short filament at the inline-start edge, in the
 * proportions of the mark (never full height, never touching the ends). */
.nav-item[aria-current="page"]::before {
  content: ""; position: absolute;
  inset-inline-start: 0; inset-block: 25%;
  inline-size: 2px; border-radius: var(--r-full);
  background: var(--accent-3);
}
.nav-item[aria-current="page"] .nav-item-icon { color: var(--accent-3); }
/* The needs-a-person count is the one nav element that glows. */
.nav-item-badge.badge-warning { box-shadow: var(--glow-attention); }
.nav-item:focus-visible { box-shadow: var(--focus-ring-inverse); }
.nav-item-icon { flex: none; }
.nav-item-badge { margin-inline-start: auto; }

.app-shell.is-rail .nav-item-label,
.app-shell.is-rail .nav-group-label,
.app-shell.is-rail .app-brand-text,
.app-shell.is-rail .nav-directory-summary-label,
.app-shell.is-rail .nav-directory-chevron { display: none; }
.app-shell.is-rail .app-brand { justify-content: center; padding-inline: 0; }
.app-shell.is-rail .nav-item { justify-content: center; padding-inline: 0; }
.app-shell.is-rail .nav-directory-summary { justify-content:center; padding-inline:0; }

.app-main { display: flex; flex-direction: column; min-inline-size: 0; }

.app-header {
  display: flex; align-items: center; gap: var(--s-4);
  block-size: var(--header-h); flex: none;
  padding-inline: var(--gutter);
  background: var(--bg-canvas);
  border-block-end: var(--bw) solid var(--border-subtle);
  position: sticky; inset-block-start: 0; z-index: var(--z-sticky);
}
.header-preferences { display: flex; align-items: center; gap: var(--s-2); }
.header-preference .select {
  inline-size: auto; min-inline-size: 104px; min-block-size: 34px;
  padding-block: var(--s-1); border-radius: var(--r-full); font-size: var(--t-secondary-size);
}
.header-preferences[aria-busy="true"] { opacity: .7; }
/* Phones: the header held two 104px selects, a labelled search button and two
 * icon buttons in 390px and pushed the document ~26px wide on every screen.
 * The sidebar toggle does nothing below the tab-bar breakpoint, the search
 * label stays for screen readers only, and the selects size to their value. */
@media (max-width: 767px) {
  .app-header { gap: var(--s-2); padding-inline: var(--s-5); }
  .app-header [data-nav-toggle] { display: none; }
  .header-preference .select { min-inline-size: 0; padding-inline-start: var(--s-4); padding-inline-end: var(--s-8); }
  [data-open-palette] { inline-size: var(--h-sm); padding-inline: 0; }
  [data-open-palette] .kbd { display: none; }
  [data-open-palette] > span:not(.kbd) {
    position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }
}
.page-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-5);
  min-block-size: var(--pageheader-h); flex: none;
  padding: var(--s-6) var(--gutter) var(--s-5);
  background: var(--bg-canvas);
  border-block-end: var(--bw) solid var(--border-subtle);
}
.page-content { flex: 1 1 auto; padding: var(--gutter); min-inline-size: 0; }
.page-content.is-flush { padding: 0; }

/* Phones: sidebar becomes a bottom tab bar. */
.tabbar { display: none; }
@media (max-width: 767px) {
  .app-shell, .app-shell.is-rail { grid-template-columns: minmax(0, 1fr); }
  .app-nav { display: none; }
  .app-main { padding-block-end: 56px; }
  .tabbar {
    position: fixed; inset-inline: 0; inset-block-end: 0; z-index: var(--z-nav);
    display: flex; align-items: stretch;
    block-size: 56px;
    background: var(--bg-inverse);
    border-block-start: var(--bw) solid var(--border-default);
    padding-block-end: env(safe-area-inset-bottom);
  }
  .tabbar-item {
    flex: 1 1 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 2px;
    color: var(--text-inverse-subtle);
    font-size: var(--t-meta-size);
    min-block-size: 44px;
    position: relative;
  }
  .tabbar-item[aria-current="page"] { color: var(--text-inverse); }
  .tabbar-item[aria-current="page"] svg { color: var(--accent-3); }
  .tabbar-item[aria-current="page"]::before {
    content: ""; position: absolute; inset-block-start: 0; inset-inline: 38%;
    block-size: 2px; border-radius: var(--r-full); background: var(--accent-3);
  }
  .tabbar-item:focus-visible { box-shadow: var(--focus-ring); }
}

/* =============================================== COMMAND PALETTE ======= */

.palette {
  inline-size: min(560px, 100%);
  align-self: start; margin-block-start: 12vh;
  background: var(--bg-surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  overflow: hidden;
  animation: dialog-in var(--dur-base) var(--ease-out);
}
.palette-input {
  inline-size: 100%; block-size: var(--h-lg);
  padding-inline: var(--s-6);
  border: 0; border-block-end: var(--bw) solid var(--border-subtle);
  font-size: var(--t-body-size);
}
.palette-input:focus-visible { box-shadow: none; }
.palette-results { max-block-size: 320px; overflow-y: auto; padding: var(--s-3); }
.palette-item {
  display: flex; align-items: center; gap: var(--s-4);
  inline-size: 100%; block-size: var(--h-lg);
  padding-inline: var(--s-4);
  border-radius: var(--r-sm);
  text-align: start;
  color: var(--text-primary);
}
.palette-item[aria-selected="true"] { background: var(--bg-selected); }
.palette-item-hint { margin-inline-start: auto; color: var(--text-tertiary); font-size: var(--t-meta-size); }
.palette-group {
  padding: var(--s-4) var(--s-4) var(--s-2);
  font-size: var(--t-overline-size); font-weight: var(--t-overline-w);
  letter-spacing: var(--t-overline-ls); text-transform: uppercase;
  color: var(--text-tertiary);
}
.kbd {
  display: inline-flex; align-items: center;
  block-size: 18px; padding-inline: var(--s-2);
  background: var(--bg-sunken);
  border: var(--bw) solid var(--border-default);
  border-radius: var(--r-xs);
  font-family: var(--font-mono); font-size: 10px;
  color: var(--text-secondary);
}

/* Icons inherit text colour and never shrink in a flex row. */
.icon { display: block; flex: none; color: currentColor; }
