/* ===========================================================================
   Tasneef Portal — application component layer
   ---------------------------------------------------------------------------
   Built ON TOP of the Tasnef Design System tokens in /css/tokens/*, and
   matched to the "Tasnef Admin Dashboard" design: measurements below are taken
   from that design rather than invented.

   Design decisions carried over verbatim:
     · The page is WHITE. Separation comes from #EDEDED hairlines plus a
       0 1px 2px rgba(0,0,0,.02) micro-shadow — not from a grey band.
     · Sidebar 230px, purple. Nav items 8px radius; the active item is a white
       pill with purple ink.
     · Stat cards 14px radius; section cards 16px; buttons are pills.
     · Table header sits on #F9F9F9 with the OUTER corners rounded.
     · Success is the Facilities green #0A4333 on #E7F1ED. Purple stays the
       brand and marks actions and figures.
     · Hover on a filled button INVERTS it; never darkens.

   NUMERALS: every digit rendered by the app goes through src/lib/format.js,
   which emits Latin digits and Gregorian dates. Templates must not call
   toLocaleDateString. `.num` additionally forces LTR + tabular figures so
   columns of numbers align.

   Contents
     1  Base            6  Cards / stats     11  Steps / breadcrumb
     2  Layout          7  Alerts            12  Modal
     3  Buttons         8  Tables            13  Empty / pager / misc
     4  Forms           9  Toolbar           14  Auth
     5  Chips / badges  10 Tabs              15  Shell · 16 Errors · 17 Print
   =========================================================================== */

/* ---------------------------------------------------------------------------
   1. Base
   --------------------------------------------------------------------------- */
:root {
  /* Portal-level additions the design uses but the token mirror has no name for */
  --success-ink: #0a4333;   /* Facilities green — the design's "مكتمل" badge */
  --success-bg:  #e7f1ed;
  /* TEXT-safe amber. --state-warning (#c98a12) is the fill/border/dot colour
     and measures 2.95:1 on white — it fails WCAG AA even at large sizes, so
     it must never carry text. This ink is 6.32:1 on white and the dark theme
     overrides it to #e0a94a for 8.15:1 there. */
  /* Badge INK is separate from the fill colour it sits on. In dark mode the
     brand green that works as a button fill (brand-300) measures 3.08:1 as
     text on a tinted badge — legible as a large heading, not as a 13px label. */
  --brand-ink: var(--brand-primary);
  --warning-ink: #7a5b00;
  --warning-bg:  #fdf6dc;
  --warning-dot: #c9a400;
  --neutral-ink: #6c6c6c;
  --neutral-bg:  #f4f4f4;
  --brand-soft-bg: var(--brand-50);  /* "قيد التطوير" badge fill — Facilities mint, was Clean lilac */
  --row-line: #f1f1f1;       /* table row separator, lighter than the hairline */
  --card-shadow: 0 1px 2px rgba(0, 0, 0, .02);
  --sidebar-width: 252px;   /* design says 236; widened for the larger nav type */
}

body {
  min-height: 100dvh;
  background: var(--surface-page);
  -webkit-font-smoothing: antialiased;
  transition: background-color var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard);
}

a { color: var(--text-link); }
a:hover { color: var(--text-link-hover); }
[hidden] { display: none !important; }

p { line-height: 1.9; text-wrap: pretty; }

.muted { color: var(--text-muted); }
.link  { color: var(--text-link); font-weight: var(--font-weight-medium); }
.link:hover { opacity: .7; }
.nowrap { white-space: nowrap; }

/* Numbers, codes, dates: always LTR and tabular so columns line up. */
.num {
  font-family: var(--font-family-numeric);
  font-variant-numeric: tabular-nums;
  direction: ltr;
  unicode-bidi: isolate;
}

/* Slim scrollbars, as the design specifies */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb { background: #00000022; border-radius: 10px; }
::-webkit-scrollbar-track { background: transparent; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* ---------------------------------------------------------------------------
   2. Layout
   --------------------------------------------------------------------------- */
.stack { display: flex; flex-direction: column; gap: var(--space-4); }
.row   { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.row--between { justify-content: space-between; }
.grid  { display: grid; gap: 16px; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

/* Page header: actions on one side, title block on the other. wrap-reverse
   keeps the title above the actions when it wraps on narrow screens. */
.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap-reverse;
}
.page-head__actions { display: flex; gap: 12px; flex-wrap: wrap; }
.page-head__text-block { text-align: start; }
.page-head__title { margin-bottom: 6px; font-size: 26px; font-weight: var(--font-weight-medium); color: var(--text-heading); }
.page-head__text  { font-size: var(--font-size-sm); color: var(--text-muted); }

.section-title { font: var(--type-h3); text-align: center; }

/* The four-point sparkle, the brand's signature motif */
.sparkle {
  display: inline-block;
  width: 1em; height: 1em;
  background: currentColor;
  -webkit-mask: url("/img/sparkle.svg") center / contain no-repeat;
  mask: url("/img/sparkle.svg") center / contain no-repeat;
}

/* ---------------------------------------------------------------------------
   3. Buttons — pills; hover inverts
   --------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 11px 24px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  line-height: 1.2;
  cursor: pointer;
  transition: all .4s var(--ease-standard);
}
.btn:hover { text-decoration: none; }
.btn svg { width: 17px; height: 17px; flex: none; }

.btn--primary {
  background: var(--brand-primary);
  border-color: var(--brand-primary);
  color: var(--text-on-brand);
}
.btn--primary:hover:not(:disabled) { background: var(--surface-card); color: var(--brand-primary); }

/* The design's secondary: white with a grey outline, filling purple on hover */
.btn--secondary {
  background: var(--surface-card);
  border-color: var(--border-field);
  color: var(--text-body);
  font-weight: var(--font-weight-regular);
}
.btn--secondary:hover:not(:disabled) {
  background: var(--brand-primary);
  border-color: var(--brand-primary);
  color: var(--text-on-brand);
}

/* Outline in brand purple — for the canonical filled + outline pairing */
.btn--outline {
  background: transparent;
  border-color: var(--brand-primary);
  color: var(--brand-primary);
}
.btn--outline:hover:not(:disabled) { background: var(--brand-primary); color: var(--text-on-brand); }

.btn--deep {
  background: var(--surface-brand-deep);
  border-color: var(--surface-brand-deep);
  color: var(--text-on-brand);
}
.btn--deep:hover:not(:disabled) { background: var(--surface-card); color: var(--surface-brand-deep); }

.btn--light {
  background: var(--white);
  border-color: var(--white);
  color: var(--brand-primary);
}
.btn--light:hover:not(:disabled) { background: transparent; color: var(--text-on-brand); }

.btn--ghost {
  background: transparent;
  border-color: var(--border-hairline);
  color: var(--text-body);
  font-weight: var(--font-weight-regular);
}
.btn--ghost:hover:not(:disabled) {
  background: var(--brand-primary);
  border-color: var(--brand-primary);
  color: var(--text-on-brand);
}

.btn--danger {
  background: var(--state-danger);
  border-color: var(--state-danger);
  color: var(--white);
}
.btn--danger:hover:not(:disabled) { background: var(--surface-card); color: var(--state-danger); }

.btn--sm { padding: 8px 18px; font-size: 13px; }
.btn--lg { padding: 14px 30px; font-size: var(--font-size-md); }
.btn--block { width: 100%; }

.btn:disabled,
.btn.is-loading {
  background: var(--grey-150);
  border-color: var(--grey-150);
  color: var(--grey-400);
  cursor: not-allowed;
}

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 36px; height: 36px;
  background: transparent;
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-circle);
  color: var(--text-muted);
  cursor: pointer;
  transition: all var(--duration-fast) var(--ease-standard);
}
.icon-btn:hover { color: var(--brand-primary); border-color: var(--brand-primary); }
.icon-btn svg { width: 17px; height: 17px; }

.spinner {
  width: 15px; height: 15px;
  border: 2px solid rgba(0, 0, 0, .18);
  border-top-color: var(--grey-400);
  border-radius: var(--radius-circle);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------------------------------------------------------------------------
   4. Forms
   --------------------------------------------------------------------------- */
.form { display: flex; flex-direction: column; gap: 18px; }
.form__row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 18px; }

.field { display: flex; flex-direction: column; gap: 8px; }
.field__label { font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); color: var(--text-heading); }
.field__label .req { color: var(--state-danger); }

.field__input,
.field__select,
.field__textarea {
  width: 100%;
  min-height: var(--control-height-md);
  padding-inline: var(--space-4);
  background: var(--surface-field);
  border: 1px solid var(--border-field);
  border-radius: var(--radius-md);
  color: var(--text-body);
  font-family: inherit;
  transition: border-color var(--duration-fast) var(--ease-standard),
              box-shadow var(--duration-fast) var(--ease-standard);
}
.field__textarea { padding-block: 13px; min-height: 110px; resize: vertical; line-height: 1.7; }

.field__input::placeholder,
.field__textarea::placeholder { color: var(--grey-400); }

.field__input:hover, .field__select:hover, .field__textarea:hover { border-color: var(--grey-400); }

.field__input:focus, .field__select:focus, .field__textarea:focus {
  outline: none;
  border-color: var(--border-brand);
  box-shadow: 0 0 0 3px var(--brand-primary-soft);
}

.field__input--error, .field__select--error { border-color: var(--state-danger); }
.field__input--error:focus { box-shadow: 0 0 0 3px var(--state-danger-soft); }
.field__input:disabled, .field__select:disabled { background: var(--grey-150); color: var(--grey-400); cursor: not-allowed; }

.field__select {
  appearance: none;
  padding-inline-end: 44px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M5 7.5 10 12.5 15 7.5' stroke='%236c6c6c' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left var(--space-4) center;
  background-size: 20px;
}
[dir='ltr'] .field__select { background-position: right var(--space-4) center; }

/* Phone, email, IBAN, iqama — values that must read left to right */
.field__input--ltr { direction: ltr; text-align: start; }

.field__group { position: relative; display: flex; align-items: center; }
.field__group .field__input { padding-inline-end: 52px; }

.field__toggle {
  position: absolute;
  inset-inline-end: 5px;
  display: grid; place-items: center;
  width: 39px; height: 39px;
  background: transparent;
  border: 0;
  border-radius: var(--radius-circle);
  color: var(--text-subtle);
  cursor: pointer;
  transition: all var(--duration-fast) var(--ease-standard);
}
.field__toggle:hover { color: var(--brand-primary); background: var(--brand-soft-bg); }
.field__toggle svg { width: 19px; height: 19px; }

.field__hint  { font-size: var(--font-size-xs); color: var(--text-muted); }
.field__error { font-size: 13px; color: var(--state-danger); }

.check { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: var(--font-size-sm); }
.check input { width: 18px; height: 18px; accent-color: var(--brand-primary); cursor: pointer; }

.switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: var(--font-size-sm); }
.switch input { position: absolute; opacity: 0; pointer-events: none; }
.switch__track {
  width: 44px; height: 26px; padding: 3px;
  background: var(--grey-300);
  border-radius: var(--radius-pill);
  transition: background-color var(--duration-fast) var(--ease-standard);
}
.switch__thumb {
  display: block; width: 20px; height: 20px;
  background: var(--white);
  border-radius: var(--radius-circle);
  transition: transform var(--duration-fast) var(--ease-standard);
}
.switch input:checked + .switch__track { background: var(--brand-primary); }
.switch input:checked + .switch__track .switch__thumb { transform: translateX(-18px); }
[dir='ltr'] .switch input:checked + .switch__track .switch__thumb { transform: translateX(18px); }
.switch input:focus-visible + .switch__track { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* ---------------------------------------------------------------------------
   5. Chips and badges
   --------------------------------------------------------------------------- */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 34px;
  padding-inline: 13px;
  background: var(--surface-chip);
  border: 1px solid transparent;
  border-radius: var(--radius-md);   /* 10px — pills are for buttons only */
  font-size: 13px;
  color: var(--text-body);
  transition: all var(--duration-fast) var(--ease-standard);
}
.chip--selectable { cursor: pointer; }
.chip--selectable:hover { border-color: var(--brand-accent); }
.chip.is-selected { background: var(--brand-soft-bg); border-color: var(--brand-primary); color: var(--brand-primary); }
.chip__remove {
  display: grid; place-items: center;
  width: 18px; height: 18px;
  background: transparent; border: 0;
  border-radius: var(--radius-circle);
  color: var(--text-subtle);
  cursor: pointer;
}
.chip__remove:hover { background: var(--grey-200); color: var(--text-body); }

/* Status badge — the design's pill with a leading dot */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
  border-radius: var(--radius-pill);
  font-size: var(--font-size-xs);
  white-space: nowrap;
}
.badge__dot { width: 6px; height: 6px; border-radius: var(--radius-circle); background: currentColor; display: inline-block; }

.badge--brand   { background: var(--brand-soft-bg); color: var(--brand-ink); }
.badge--brand .badge__dot { background: var(--brand-accent); }
.badge--success { background: var(--success-bg); color: var(--success-ink); }
.badge--warning { background: var(--warning-bg); color: var(--warning-ink); }
.badge--warning .badge__dot { background: var(--warning-dot); }
.badge--danger  { background: var(--state-danger-soft); color: var(--state-danger); }
.badge--neutral { background: var(--neutral-bg); color: var(--neutral-ink); }

/* ---------------------------------------------------------------------------
   6. Cards and stat tiles
   --------------------------------------------------------------------------- */
.card {
  background: var(--surface-card);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-lg);      /* 16px */
  box-shadow: var(--card-shadow);
  overflow: hidden;
}
.card + .card { margin-top: 22px; }
.card--panel { border-radius: var(--radius-panel); }
.card--flush .card__body { padding: 0; }

.card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 18px 22px;
  border-bottom: 1px solid var(--border-hairline);
}
.card__title { font-size: 17px; font-weight: var(--font-weight-medium); color: var(--text-heading); }
.card__body  { padding: 20px 22px; }
.card__foot  {
  display: flex; gap: 10px; justify-content: flex-end;
  padding: 16px 22px;
  background: var(--surface-section);
  border-top: 1px solid var(--border-hairline);
}

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 16px; }
.stat {
  padding: 18px 20px;
  background: var(--surface-card);
  border: 1px solid var(--border-hairline);
  border-radius: 14px;
  box-shadow: var(--card-shadow);
}
.stat__label { margin-bottom: 6px; font-size: 13px; color: var(--text-muted); }
.stat__value {
  font-family: var(--font-family-numeric);
  font-variant-numeric: tabular-nums;
  font-size: 30px;
  font-weight: var(--font-weight-bold);
  line-height: 1.1;
  color: var(--brand-primary);
}
/* When the "value" is words rather than a figure */
.stat__value--text { font-size: 19px; font-family: var(--font-family-core); }
.stat__value--ink  { color: var(--text-heading); }
.stat__meta { margin-top: 6px; font-size: var(--font-size-xs); color: var(--text-muted); }

/* ---------------------------------------------------------------------------
   7. Alerts
   --------------------------------------------------------------------------- */
.alert {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 13px var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
}
.alert p { line-height: 1.6; }
.alert__icon { flex: none; width: 19px; height: 19px; margin-top: 2px; }

.alert--error   { background: var(--state-danger-soft);  border-color: var(--alert-danger-border);  color: var(--state-danger); }
.alert--success { background: var(--success-bg);         border-color: var(--alert-success-border); color: var(--success-ink); }
.alert--warning { background: var(--warning-bg);         border-color: var(--alert-warning-border); color: var(--warning-ink); }
.alert--info    { background: var(--brand-soft-bg);      border-color: var(--alert-info-border);    color: var(--brand-primary); }

:root {
  --alert-danger-border:  #f0c9c9;
  --alert-success-border: #cfe3dc;
  --alert-warning-border: #f0d9ac;
  --alert-info-border:    var(--brand-100);
}

/* ---------------------------------------------------------------------------
   8. Tables — header band with rounded outer corners
   --------------------------------------------------------------------------- */
.table-wrap { width: 100%; overflow-x: auto; }

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-sm);
}
.table thead tr { background: var(--surface-section); }
.table thead th {
  padding: 12px 16px;
  font-weight: var(--font-weight-medium);
  color: var(--text-muted);
  text-align: start;
  white-space: nowrap;
}
/* Round the band's outer ends (RTL: first cell is on the right) */
.table thead th:first-child { border-radius: 0 8px 8px 0; }
.table thead th:last-child  { border-radius: 8px 0 0 8px; }
[dir='ltr'] .table thead th:first-child { border-radius: 8px 0 0 8px; }
[dir='ltr'] .table thead th:last-child  { border-radius: 0 8px 8px 0; }

.table tbody td {
  padding: 14px 16px;
  color: var(--text-body);
  border-bottom: 1px solid var(--row-line);
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr { transition: background-color var(--duration-fast) var(--ease-standard); }
.table tbody tr:hover { background: var(--surface-section); }
.table tbody tr.is-selected { background: var(--brand-soft-bg); }

.table .is-center { text-align: center; }
.table .is-end    { text-align: end; }
.table .is-muted  { color: var(--text-muted); }
.table .is-actions { width: 1%; white-space: nowrap; }
.table td.is-num {
  font-family: var(--font-family-numeric);
  font-variant-numeric: tabular-nums;
  direction: ltr;
  unicode-bidi: isolate;
}

/* ---------------------------------------------------------------------------
   9. Toolbar / filters
   --------------------------------------------------------------------------- */
.toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 14px 16px;
  background: var(--surface-card);
  border: 1px solid var(--border-hairline);
  border-radius: 14px;
  box-shadow: var(--card-shadow);
  margin-bottom: 16px;
}
.toolbar__search { flex: 1 1 220px; min-width: 180px; }
.toolbar__spacer { flex: 1; }
.toolbar .field__input,
.toolbar .field__select { min-height: var(--control-height-sm); }

/* ---------------------------------------------------------------------------
   10. Tabs
   --------------------------------------------------------------------------- */
.tabs {
  display: flex;
  gap: 26px;
  border-bottom: 1px solid var(--border-hairline);
  margin-bottom: 18px;
  overflow-x: auto;
}
.tab {
  position: relative;
  padding: 13px 0;
  background: none; border: 0;
  font-family: inherit;
  font-size: var(--font-size-sm);
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--duration-fast) var(--ease-standard);
}
.tab:hover { color: var(--text-body); }
.tab.is-active { color: var(--brand-primary); font-weight: var(--font-weight-medium); }
.tab.is-active::after {
  content: '';
  position: absolute; inset-inline: 0; bottom: -1px;
  height: 2px; background: var(--brand-primary); border-radius: var(--radius-xs);
}

/* ---------------------------------------------------------------------------
   11. Steps and breadcrumb
   --------------------------------------------------------------------------- */
.steps { display: flex; gap: 14px; justify-content: center; margin-bottom: 24px; }
.step { flex: 0 1 160px; text-align: center; }
.step__bar { height: 3px; background: var(--grey-200); border-radius: var(--radius-xs); transition: background-color var(--duration-base) var(--ease-standard); }
.step__label { margin-top: 10px; font-size: var(--font-size-xs); color: var(--text-subtle); }
.step.is-done .step__bar   { background: var(--brand-accent); }
.step.is-active .step__bar { background: var(--brand-primary); }
.step.is-active .step__label { color: var(--brand-primary); font-weight: var(--font-weight-medium); }

.crumbs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; font-size: var(--font-size-xs); }
.crumbs a { color: var(--text-crumb); }
.crumbs a:hover { color: var(--brand-primary); }
.crumbs__sep { color: var(--text-crumb); }
.crumbs__current { color: var(--text-body); }

/* ---------------------------------------------------------------------------
   12. Modal
   --------------------------------------------------------------------------- */
.modal {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center;
  padding: var(--space-4);
  background: var(--overlay-scrim);
}
.modal__panel {
  width: 100%; max-width: 560px; max-height: 88dvh;
  display: flex; flex-direction: column;
  background: var(--surface-card);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-modal);
  overflow: hidden;
}
.modal__header {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: 18px 22px;
  border-bottom: 1px solid var(--border-hairline);
}
.modal__title { font-size: 17px; font-weight: var(--font-weight-medium); }
.modal__body  { padding: 20px 22px; overflow-y: auto; }
.modal__foot  {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  padding: 16px 22px;
  background: var(--surface-section);
  border-top: 1px solid var(--border-hairline);
}

/* ---------------------------------------------------------------------------
   13. Empty state, pager, avatar, skeleton
   --------------------------------------------------------------------------- */
.empty { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 60px var(--space-5); text-align: center; }
.empty__mark  { font-size: 38px; color: var(--brand-accent); opacity: .5; }
.empty__title { font-size: 17px; font-weight: var(--font-weight-medium); }
.empty__text  { font-size: var(--font-size-sm); color: var(--text-muted); max-width: 380px; }

.pager { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding-top: 18px; }
.pager__info { font-size: var(--font-size-xs); color: var(--text-muted); }
.pager__controls { display: flex; gap: 6px; }
.pager__btn {
  min-width: 36px; height: 36px;
  display: grid; place-items: center;
  padding-inline: 10px;
  background: var(--surface-card);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-md);
  font-family: inherit; font-size: 13px;
  color: var(--text-body);
  cursor: pointer;
  transition: all var(--duration-fast) var(--ease-standard);
}
.pager__btn:hover:not(:disabled) { border-color: var(--brand-primary); color: var(--brand-primary); }
.pager__btn.is-active { background: var(--brand-primary); border-color: var(--brand-primary); color: var(--text-on-brand); }
.pager__btn:disabled { opacity: .45; cursor: not-allowed; }

.avatar {
  display: grid; place-items: center;
  width: 38px; height: 38px; flex: none;
  background: var(--brand-soft-bg);
  color: var(--brand-primary);
  border-radius: var(--radius-circle);
  font-size: 13px; font-weight: var(--font-weight-medium);
}

.skeleton {
  background: linear-gradient(90deg, var(--grey-150) 25%, var(--grey-100) 37%, var(--grey-150) 63%);
  background-size: 400% 100%;
  border-radius: var(--radius-sm);
  animation: shimmer 1.4s ease infinite;
}
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }

/* ===========================================================================
   14. Auth — Admin Login (Tasnef Facilities design)
   ===========================================================================
   Two panels: the form on the left, a green brand band on the right. The
   design's phone/OTP flow is replaced by the real username+password credential
   (see the note in login.ejs); everything else follows the source. */
.login {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  min-height: 100dvh;
  background: var(--white);
}

/* --- left: form ----------------------------------------------------------- */
.login__main {
  flex: 1 1 480px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 40px clamp(24px, 6vw, 88px);
}

.login__head { display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.login__logo { height: 46px; width: auto; }

.login__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: 56px 32px;
  max-width: 460px;
  width: 100%;
}

.login__overline {
  margin: 0 0 12px;
  font-size: 14px;
  font-weight: var(--font-weight-medium);
  letter-spacing: .04em;
  color: var(--brand-300);
}
.login__title {
  margin: 0 0 12px;
  font-size: 40px;
  line-height: 1.2;
  font-weight: var(--font-weight-medium);
  color: #111;
  text-wrap: pretty;
}
.login__subtitle {
  margin: 0 0 32px;
  font-size: var(--font-size-md);
  line-height: 1.7;
  color: var(--grey-700);
  text-wrap: pretty;
}

.login__alert {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 20px;
  padding: 14px 16px;
  border: 1px solid #F3C9C9;
  border-radius: 10px;
  background: #FDF3F3;
  font-size: var(--font-size-sm);
  line-height: 1.6;
  color: #9C2B2B;
}
.login__alert-mark { font-weight: var(--font-weight-bold); }

.login__form { display: grid; gap: 22px; }
.login__field { display: grid; gap: 8px; }
.login__label { font-size: 14px; font-weight: var(--font-weight-medium); color: #111; }

.login__control {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 56px;
  padding: 0 18px;
  border: 1px solid var(--border-field);
  border-radius: 10px;
  background: var(--white);
  transition: border-color var(--duration-base) var(--ease-standard),
              box-shadow var(--duration-base) var(--ease-standard);
}
.login__control:focus-within {
  border-color: var(--brand-600);
  box-shadow: 0 0 0 3px var(--brand-50);
}

.login__input {
  flex: 1;
  min-width: 0;
  height: 100%;
  border: 0;
  outline: none;
  background: transparent;
  font-family: inherit;
  font-size: 17px;
  color: #111;
}

.login__reveal {
  flex: none;
  width: 24px; height: 24px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-subtle);
  cursor: pointer;
}
.login__reveal svg { width: 20px; height: 20px; }
.login__reveal:hover { color: var(--brand-600); }

.login__hint { margin: 0; font-size: 13px; line-height: 1.6; color: var(--text-subtle); }

.login__submit {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 56px;
  border: 1px solid var(--brand-600);
  border-radius: var(--radius-pill);
  background: var(--brand-600);
  font-family: inherit;
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-medium);
  color: var(--white);
  cursor: pointer;
  transition: background-color var(--duration-base) var(--ease-standard),
              color var(--duration-base) var(--ease-standard);
}
.login__submit:hover:not(:disabled) { background: var(--white); color: var(--brand-600); }
.login__submit:disabled { opacity: .8; cursor: default; }

.login__spinner {
  width: 16px; height: 16px;
  border: 2px solid rgba(255, 255, 255, .35);
  border-top-color: var(--white);
  border-radius: 50%;
  animation: login-spin .7s linear infinite;
}
@keyframes login-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .login__spinner { animation: none; } }

.login__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 20px;
  padding-top: 24px;
  border-top: 1px solid var(--border-hairline);
  font-size: 13px;
  line-height: 1.6;
  color: var(--grey-400);
}

/* --- right: brand band ---------------------------------------------------- */
.login__aside {
  flex: 1 1 420px;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 420px;
  padding: clamp(32px, 5vw, 64px);
  background: var(--surface-brand);
  overflow: hidden;
}
/* The hero video fills the band; a green wash over it keeps the white text
   legible whatever frame is on screen. */
.login__aside-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.login__aside-tint {
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg,
    rgba(10, 67, 51, .62) 0%,
    rgba(10, 67, 51, .78) 55%,
    rgba(6, 35, 27, .92) 100%);
}
.login__aside-logo {
  position: relative;
  align-self: flex-start;
  height: 52px;
  width: auto;
  margin-bottom: auto;
  opacity: .95;
}
.login__aside-body { position: relative; max-width: 460px; }
.login__aside-title {
  margin: 0 0 18px;
  font-size: 34px;
  line-height: 1.35;
  font-weight: var(--font-weight-medium);
  color: var(--white);
  text-wrap: pretty;
}
.login__aside-text {
  margin: 0 0 28px;
  font-size: 17px;
  line-height: 1.8;
  color: rgba(255, 255, 255, .82);
  text-wrap: pretty;
}
.login__aside-tag {
  margin: 0;
  font-size: 15px;
  font-weight: var(--font-weight-medium);
  letter-spacing: .02em;
  color: var(--white);
}

/* On a phone the band drops below the form and shrinks to a footer strip. */
@media (max-width: 820px) {
  .login__main { flex-basis: 100%; padding: 28px 22px; }
  .login__body { padding-block: 32px 24px; }
  .login__title { font-size: 32px; }
  .login__aside { flex-basis: 100%; min-height: 220px; justify-content: flex-end; }
  .login__aside-logo { display: none; }
  .login__aside-title { font-size: 24px; margin-bottom: 12px; }
  .login__aside-text { font-size: 15px; margin-bottom: 14px; }
}

/* ===========================================================================
   15. App shell
   =========================================================================== */
.shell { display: grid; grid-template-columns: var(--sidebar-width) minmax(0, 1fr); min-height: 100dvh; background: var(--surface-page); }

.shell__sidebar {
  display: flex; flex-direction: column; gap: 2px;
  padding: 0 0 28px;
  background: var(--surface-brand);
  color: var(--text-on-brand);
  /* align-self:start is what makes position:sticky work inside the grid — a
     stretched item is already the full row height, so sticky has nothing to
     do. But "start" sizes the item to its CONTENT, which left the purple
     field ending partway down the page on tall screens. An explicit viewport
     height fixes that: the field always fills the screen, and a nav longer
     than the viewport scrolls inside it. */
  position: sticky; top: 0; align-self: start;
  height: 100dvh; overflow-y: auto;
}
.shell__brand {
  display: flex;
  padding: 20px 20px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, .12);
}
.shell__brand img { height: 30px; width: auto; display: block; }

.nav { padding: 12px 10px 24px; display: flex; flex-direction: column; gap: 4px; }

/* --- collapsible groups ----------------------------------------------------
   <details> with the native marker removed. Safari still draws it through
   ::-webkit-details-marker, so both are cleared. */
.nav__group { border-radius: 8px; }
.nav__group > summary::-webkit-details-marker { display: none; }
.nav__group > summary { list-style: none; }

.nav__group-head {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px;
  border-radius: 8px;
  cursor: pointer;
  user-select: none;
  transition: background-color var(--duration-fast) var(--ease-standard);
}
.nav__group-head:hover { background: rgba(255, 255, 255, .08); }
.nav__group-head:focus-visible { outline: 2px solid var(--white); outline-offset: -2px; }

.nav__group-icon { flex: none; display: flex; color: var(--brand-200); }

/* 14px, NOT the design's 13px. The registry is long enough that the group
   headers carry real navigational weight, and a sidebar you have to lean in
   to read is a sidebar people stop using. */
.nav__group-label {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  letter-spacing: .04em;
  color: var(--brand-200);
}

.nav__group-count { flex: none; font-size: 11px; color: rgba(255, 255, 255, .45); }

.nav__group-chevron {
  flex: none;
  display: flex;
  color: var(--brand-200);
  transition: transform var(--duration-base) var(--ease-standard);
}
.nav__group[open] .nav__group-chevron { transform: rotate(180deg); }
.nav__group[open] .nav__group-label,
.nav__group[open] .nav__group-icon { color: var(--white); }

.nav__list {
  list-style: none;
  margin: 0;
  padding: 2px 0 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.nav__link {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px 9px 12px;
  border-radius: 8px;
  color: rgba(255, 255, 255, .88);
  /* 15px — a step ABOVE both the old 14px and the design's 13.5px. */
  font-size: var(--font-size-md);
  transition: background-color var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard);
}

/* The accent bar that marks the selected row in the design. Always present so
   the label sits on the same line whether or not the row is active — a bar
   that appears only when selected shifts every other row sideways. */
.nav__bar {
  flex: none;
  width: 3px;
  height: 17px;
  border-radius: 2px;
  background: transparent;
  transition: background-color var(--duration-fast) var(--ease-standard);
}

.nav__label { flex: 1 1 auto; min-width: 0; }

.nav__link:hover {
  background: rgba(255, 255, 255, .1);
  color: var(--text-on-brand);
  text-decoration: none;
}
.nav__link:hover .nav__bar { background: var(--brand-200); }

.nav__link.is-active {
  background: var(--white);
  color: var(--brand-primary);
  font-weight: var(--font-weight-medium);
}
.nav__link.is-active .nav__bar { background: var(--brand-primary); }

.nav__link.is-planned { color: rgba(255, 255, 255, .6); cursor: default; }
.nav__link.is-planned:hover { background: rgba(255, 255, 255, .06); }

.nav__badge {
  flex: none;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, .12);
  font-size: 11px;
  color: var(--brand-200);
}

.shell__main { display: flex; flex-direction: column; min-width: 0; }

/* The bar itself is full-bleed (its border must reach both edges); the inner
   wrapper carries the layout and is capped to the same width as .content, so
   the header lines up with the page beneath it on wide monitors. */
.topbar {
  position: sticky; top: 0; z-index: 5;
  display: flex;
  /* min-height, not height: the title can now carry a second line and a fixed
     bar would clip it. */
  min-height: 68px;
  padding: 0 26px;
  padding-top: env(safe-area-inset-top, 0px);
  background: var(--surface-card);
  border-bottom: 1px solid var(--border-hairline);
}
.topbar__title { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.topbar__title-main {
  font-size: 19px;
  font-weight: var(--font-weight-medium);
  color: var(--text-heading);
  line-height: 1.25;
}
.topbar__title-sub { font-size: var(--font-size-sm); color: var(--text-muted); line-height: 1.3; }
.topbar__menu {
  display: none; flex-direction: column; justify-content: center; gap: 4px;
  width: 38px; height: 38px; padding-inline: 8px;
  background: transparent;
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-md);
  cursor: pointer;
}
.topbar__menu span { display: block; height: 2px; background: var(--text-body); border-radius: var(--radius-xs); }
.topbar__user { display: flex; align-items: center; gap: 12px; }

/* The identity pill from the design: name and role on a mint field with a
   circular monogram. */
.topbar__identity {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 6px 5px 14px;
  border-radius: var(--radius-pill);
  background: var(--surface-mint);
}
.topbar__identity-text { text-align: start; line-height: 1.3; min-width: 0; }
.topbar__identity-text strong { display: block; font-size: 13px; font-weight: var(--font-weight-medium); color: var(--brand-primary); }
.topbar__identity-text span   { display: block; font-size: var(--font-size-xs); color: var(--brand-300); }

.topbar__avatar {
  flex: none;
  width: 30px; height: 30px;
  border-radius: var(--radius-circle);
  background: var(--brand-primary);
  color: var(--white);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px;
  font-weight: var(--font-weight-medium);
}

/* Sun / moon switch, matching the design's header control */
.theme-toggle {
  display: flex; align-items: center; gap: 2px;
  padding: 4px;
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-pill);
}
.theme-toggle__btn {
  display: grid; place-items: center;
  width: 30px; height: 30px;
  background: transparent;
  border: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-standard);
}
.theme-toggle__btn img,
.theme-toggle__btn svg { width: 15px; height: 15px; opacity: .55; }
.theme-toggle__btn:hover { background: var(--surface-chip); }
/* The live site puts the SELECTED half on plain white — `.mode .light` and
   `.thame-dark .mode .dark` both take `background-color:#fff`. Ours was on a
   pale lilac left over from the Clean palette. */
.theme-toggle__btn.is-active { background: var(--white); box-shadow: var(--shadow-tile); }
.theme-toggle__btn.is-active img,
.theme-toggle__btn.is-active svg { opacity: 1; }

.content {
  flex: 1;
  display: flex; flex-direction: column; gap: 22px;
  /* Cap the reading width on large monitors. Without this the dashboard
     stretched the full width of the screen, which makes headings and table
     rows uncomfortably long. Wide tables still scroll inside .table-wrap. */
  width: 100%;
  max-width: var(--container-max);   /* 1320px */
  margin-inline: auto;
  padding: 28px 26px 48px;
  padding-bottom: calc(48px + env(safe-area-inset-bottom, 0px));
}

/* Screens wide enough that even the capped column floats in space: keep the
   topbar aligned with the content beneath it rather than hugging the edges. */
.topbar__inner {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
}

.shell__scrim { position: fixed; inset: 0; z-index: 25; background: var(--overlay-scrim); }

@media (max-width: 1024px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .shell__sidebar {
    position: fixed; inset-block: 0; inset-inline-start: 0; z-index: 30;
    width: var(--sidebar-width);
    max-height: 100dvh;
    transform: translateX(100%);
    transition: transform var(--duration-fast) var(--ease-standard);
    box-shadow: var(--shadow-modal);
  }
  [dir='ltr'] .shell__sidebar { transform: translateX(-100%); }
  .shell__sidebar.is-open { transform: translateX(0); }
  .topbar { padding: 0 16px; }
  .topbar__inner { justify-content: flex-start; gap: 12px; }
  .topbar__menu { display: flex; }
  .topbar__title { flex: 1; }
  .topbar__identity { display: none; }
  .content { padding: 20px 16px 40px; }
}

/* ===========================================================================
   16. Error page
   =========================================================================== */
.error-page { display: grid; place-items: center; min-height: 100dvh; padding: var(--space-5); background: var(--surface-section); }
.error-page__inner { max-width: 480px; text-align: center; }
.error-page__status {
  font-family: var(--font-family-numeric);
  font-size: 44px; font-weight: var(--font-weight-bold);
  color: var(--brand-primary);
  direction: ltr;
}
.error-page__title { margin-top: 8px; font-size: 24px; font-weight: var(--font-weight-medium); }
.error-page__message { margin-top: 10px; color: var(--text-muted); }
.error-page__actions { margin-top: 24px; }
.error-page__detail {
  margin-top: 18px; padding: var(--space-4);
  background: var(--surface-chip);
  border-radius: var(--radius-md);
  font-size: var(--font-size-xs);
  text-align: start; direction: ltr;
  overflow-x: auto; white-space: pre-wrap; word-break: break-word;
}

/* ===========================================================================
   17. Styleguide (development only)
   =========================================================================== */
.sg__section { margin-bottom: 44px; }
.sg__heading { padding-bottom: 10px; margin-bottom: 18px; border-bottom: 1px solid var(--border-hairline); font-size: 17px; font-weight: var(--font-weight-medium); }
.sg__row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 14px; }
.sg__swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 14px; }
.sg__swatch { border: 1px solid var(--border-hairline); border-radius: var(--radius-md); overflow: hidden; }
.sg__swatch-chip { height: 56px; }
.sg__swatch-name { padding: 10px; font-size: var(--font-size-xs); }
.sg__note { font-size: var(--font-size-xs); color: var(--text-muted); margin-bottom: 14px; }

/* ===========================================================================
   18. Print
   =========================================================================== */
@media print {
  .shell__sidebar, .topbar, .shell__scrim, .toolbar, .pager, .btn, .modal { display: none !important; }
  .shell { grid-template-columns: 1fr; }
  body, .shell__main { background: var(--white); }
  .content { padding: 0; }
  .card { border: 1px solid var(--grey-300); box-shadow: none; }
}

/* ---------------------------------------------------------------------------
   Public report share  (/r/:token)
   ---------------------------------------------------------------------------
   The one set of screens a client sees. No sidebar, no navigation, nothing
   that implies there is a system behind it — a shared report is a document,
   not an application window. Built on the same tokens as everything else so
   it still looks like Tasnef.
   --------------------------------------------------------------------------- */
.share {
  max-width: 900px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-4) var(--space-10);
}

.share--center {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 80vh;
}

.share__head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-5);
  flex-wrap: wrap;
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--border-subtle);
  margin-bottom: var(--space-6);
}

.share__logo { height: 28px; width: auto; }

.share__title {
  font-size: var(--font-size-2xl);
  font-weight: 600;
  margin: 0 0 var(--space-2);
  color: var(--text-strong);
}

.share__meta {
  margin: 0 0 var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--text-muted);
}

.share__card {
  background: var(--surface-raised);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  margin-bottom: var(--space-5);
}

.share__card--notice { text-align: center; max-width: 420px; }
.share__card--notice .share__logo { margin-bottom: var(--space-5); }

.share__section-title {
  font-size: var(--font-size-lg);
  font-weight: 600;
  margin: 0 0 var(--space-3);
  color: var(--text-strong);
}

.share__badge {
  display: inline-block;
  font-size: var(--font-size-xs);
  font-weight: 400;
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
  color: var(--text-muted);
  margin-inline-start: var(--space-2);
  vertical-align: middle;
}

.share__text { margin: 0 0 var(--space-3); line-height: 1.7; }
.share__text--muted { color: var(--text-muted); font-size: var(--font-size-sm); }

.share__phase {
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--text-muted);
  margin: var(--space-4) 0 var(--space-2);
}

/* auto-fill, so one photograph does not stretch across the whole row */
.share__gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--space-3);
}

.share__figure { margin: 0; }

.share__image {
  width: 100%;
  height: 180px;
  object-fit: cover;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-subtle);
  background: var(--surface-sunken);
}

.share__caption {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  margin-top: var(--space-1);
}

.share__foot {
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border-subtle);
  text-align: center;
}

@media (max-width: 600px) {
  .share__image { height: 140px; }
  .share__gallery { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}

/* ---------------------------------------------------------------------------
   Boosted navigation — the progress bar, and the swap itself.
   ---------------------------------------------------------------------------
   Pages arrive in well under 100ms on the server, so a spinner would flash and
   vanish and read as a glitch. A thin bar along the top edge is enough to say
   "it heard you" without drawing the eye, and it is delayed so that fast
   navigations — which is nearly all of them — show nothing at all.
   --------------------------------------------------------------------------- */
.nav-progress {
  position: fixed;
  inset-block-start: 0;
  inset-inline-start: 0;
  block-size: 2px;
  inline-size: 0;
  background: var(--brand-accent, #56796f);
  z-index: 9999;
  opacity: 0;
  pointer-events: none;
}

/* htmx adds .htmx-request to the indicator for the life of the request. */
.nav-progress.htmx-request {
  opacity: 1;
  /* Creeps toward 90% and waits: the real duration is unknown, and a bar that
     completes before the page arrives is a lie the eye notices. */
  animation: nav-progress-grow 1.6s cubic-bezier(.2, .8, .3, 1) forwards;
  animation-delay: 120ms;
}

@keyframes nav-progress-grow {
  0%   { inline-size: 0;   opacity: 1; }
  60%  { inline-size: 62%; }
  100% { inline-size: 90%; opacity: 1; }
}

/* THERE IS DELIBERATELY NO FADE HERE ANY MORE.
   `.shell__main` used to be the element htmx swapped, and it faded from .55 so
   the incoming page did not snap into place. It is no longer swapped — `#page`
   is — so the rule had stopped doing what it said: it ran once per full page
   load and dimmed the entire shell, sidebar included, which reads as a flash
   on first paint and buys nothing. Moving it onto `#page` would have been
   worse: a fade on every single navigation is exactly the flicker it was
   supposed to prevent. A swap that lands in one frame needs no transition. */

/* Someone who has asked for less motion gets none of it. */
@media (prefers-reduced-motion: reduce) {
  .nav-progress.htmx-request { animation: none; inline-size: 90%; }
}

/* SCROLL ANCHORING OFF for the swapped region.
   Chrome keeps a visual anchor when content above the viewport changes height,
   and a page swap changes it by the entire document. After the reset to the
   top it was nudging the page back down ~22px — a small bounce, but on top of
   the reset it is what made a navigation look like it wobbled. */
.content { overflow-anchor: none; }

/* ---------------------------------------------------------------------------
   Topbar on the brand field.
   ---------------------------------------------------------------------------
   The bar carries the same green as the sidebar, so the two read as one shell
   and the page content sits inside it rather than beside it. Everything in the
   bar therefore sits ON the brand, and every control has to be restated for a
   dark field — a white-on-white logout button would simply vanish.

   Scoped under .topbar rather than changing the components themselves: the
   same .btn--ghost is used on white cards everywhere else and must stay as it
   is there.
   --------------------------------------------------------------------------- */
.topbar {
  background: var(--surface-brand);
  border-bottom-color: rgba(255, 255, 255, .12);
}

.topbar__title-main { color: var(--text-on-brand); }
.topbar__title-sub  { color: var(--brand-200); }

/* The identity pill is a MINT pill on white everywhere the design shows it;
   on the brand field that is mint on green, which is nearly invisible and puts
   dark-green text on a pale field sitting on a dark one. It becomes the same
   translucent-white treatment the portal's dialog heads use. */
.topbar__identity { background: rgba(255, 255, 255, .12); }
.topbar__identity-text strong { color: var(--text-on-brand); }
.topbar__identity-text span   { color: var(--brand-200); }
.topbar__avatar { background: var(--white); color: var(--brand-primary); }

/* Outline pill in white — the design's `light` button variant, which exists
   precisely for a green field. */
.topbar .btn--ghost {
  background: transparent;
  border-color: rgba(255, 255, 255, .45);
  color: var(--text-on-brand);
}

.topbar .btn--ghost:hover:not(:disabled) {
  background: var(--white);
  border-color: var(--white);
  color: var(--brand-primary);       /* hover INVERTS the fill, never darkens */
}

/* The sun / moon switch keeps its shape; only the field it sits on changes. */
.topbar .theme-toggle { border-color: rgba(255, 255, 255, .35); }

.topbar .theme-toggle__btn img,
.topbar .theme-toggle__btn svg { filter: brightness(0) invert(1); opacity: .65; }

.topbar .theme-toggle__btn:hover { background: rgba(255, 255, 255, .12); }

/* The selected half is white, as it is on the live site — so its glyph must
   drop back to dark or it would be white on white. */
.topbar .theme-toggle__btn.is-active { background: var(--white); }
.topbar .theme-toggle__btn.is-active img,
.topbar .theme-toggle__btn.is-active svg { filter: none; opacity: 1; }

.topbar__menu {
  border-color: rgba(255, 255, 255, .45);
}
.topbar__menu span { background: var(--text-on-brand); }

/* In dark mode the bar and the sidebar share the darker surface instead, so
   the shell stays one piece there too. */
[data-theme='dark'] .topbar {
  background: var(--surface-brand);
  border-bottom-color: rgba(255, 255, 255, .08);
}

/* On a phone the bar must stay one line. The page title is the only part that
   can grow — "الحضور والانصراف" wraps to two lines on a 360px screen and adds
   ~60px of chrome above every page, on the device with the least room to spare.
   It truncates instead; the same title is repeated as the page heading directly
   below, so nothing is lost. */
@media (max-width: 720px) {
  .topbar { height: 60px; }

  .topbar__title {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--font-size-md);
  }

  /* The name and role are on the page anyway; the bar keeps the controls. */
  .topbar__identity { display: none; }
}

/* ===========================================================================
   Dashboard — the Tasnef Facilities admin design.
   ===========================================================================
   Same palette tokens as everywhere else; the sizes the design names that fall
   between steps of the type scale (19, 26, 12.5px) are written out.
   =========================================================================== */

/* --- the banner ------------------------------------------------------------ */
.hero {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--surface-brand);
  padding: 24px 26px;
}

/* The logo mark, oversized and tonal, rising from the bottom edge in the
   gap between the greeting and the actions (the client portal's hero uses the
   same mark). Below 900px that gap closes, so the mark steps aside rather
   than sit under the buttons. */
.hero__mark {
  position: absolute;
  inset-inline-start: 38%; bottom: -46px;
  height: 180px; width: auto;
  opacity: .1;
  pointer-events: none;
}
@media (max-width: 900px) { .hero__mark { display: none; } }
:root[data-theme="dark"] .hero__mark { opacity: .07; }

.hero__body {
  position: relative;
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
}

.hero__text { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.hero__date { font-size: 13px; letter-spacing: .02em; color: var(--brand-200); }

.hero__title {
  margin: 0;
  font-size: 28px; line-height: 1.2;
  font-weight: var(--font-weight-medium);
  color: var(--white);
}

.hero__meta { margin: 0; font-size: var(--font-size-sm); color: var(--brand-200); }
.hero__sep { margin: 0 8px; opacity: .6; }
.hero__note { margin: 0; font-size: 13px; color: var(--brand-200); opacity: .85; }

.hero__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.hero__btn {
  display: flex; align-items: center; gap: 8px;
  height: 40px; padding: 0 16px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--white);
  background: transparent;
  color: var(--white);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
  text-decoration: none;
  transition: var(--transition-control);
}
.hero__btn:hover { background: var(--white); color: var(--brand-primary); text-decoration: none; }

/* --- stat cards ------------------------------------------------------------ */
.stat-grid { display: flex; flex-wrap: wrap; gap: 12px; }

.stat {
  flex: 1 1 190px; min-width: 0; max-width: 340px;
  background: var(--surface-card);
  border: 1px solid var(--border-hairline);
  border-radius: 14px;
  padding: 16px 18px;
  display: flex; flex-direction: column; gap: 12px;
  text-decoration: none;
  transition: border-color var(--duration-base) var(--ease-standard);
}
.stat:hover { border-color: var(--border-brand); text-decoration: none; }

.stat__head { display: flex; align-items: center; gap: 10px; }

.stat__icon {
  flex: none;
  width: 34px; height: 34px;
  border-radius: var(--radius-circle);
  background: var(--surface-mint);
  display: flex; align-items: center; justify-content: center;
}

.stat__label { font-size: 13px; line-height: 1.4; color: var(--text-muted); }
.stat__body { display: flex; flex-direction: column; gap: 4px; }

.stat__value {
  font-size: 26px; font-weight: var(--font-weight-bold);
  line-height: 1.15;
  font-family: var(--font-family-numeric);
  color: var(--brand-primary);
}
.stat__value--warn { color: var(--warning-ink); }
.stat__value--danger { color: var(--state-danger); }
.stat__meta { font-size: var(--font-size-xs); color: var(--text-subtle); }

/* --- the two-column body --------------------------------------------------- */
.dash { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-start; }
.dash__main { flex: 1 1 380px; min-width: 0; display: flex; flex-direction: column; gap: 14px; }
.dash__side { flex: 1 1 260px; min-width: 0; max-width: 360px; display: flex; flex-direction: column; gap: 14px; }

.card__count { font-size: 12.5px; color: var(--text-subtle); }
.card__link {
  font-size: 13px; font-weight: var(--font-weight-medium);
  color: var(--brand-primary);
}
.card__foot {
  padding: 14px 20px 18px;
  display: flex; gap: 8px; flex-wrap: wrap;
}

/* --- hairline row lists ----------------------------------------------------
   The 1px gap over a grey field draws every divider, so the block reads as one
   table and keeps its rounded corners with overflow:hidden. */
.rowlist {
  margin: 0 20px 18px;
  display: flex; flex-direction: column; gap: 1px;
  background: var(--border-hairline);
  border: 1px solid var(--border-hairline);
  border-radius: 10px;
  overflow: hidden;
}

.rowlist__row {
  background: var(--surface-card);
  padding: 13px 14px;
  display: flex; align-items: center; gap: 12px;
  text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease-standard);
}
a.rowlist__row:hover { background: var(--surface-mint); text-decoration: none; }
.rowlist__row--static { cursor: default; }

.rowlist__icon {
  flex: none;
  width: 30px; height: 30px;
  border-radius: var(--radius-circle);
  display: flex; align-items: center; justify-content: center;
}
.rowlist__icon--red   { background: var(--state-danger-soft);  color: var(--state-danger); }
.rowlist__icon--amber { background: var(--state-warning-soft); color: var(--warning-ink); }
.rowlist__icon--green { background: var(--surface-mint);       color: var(--brand-primary); }

.rowlist__text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.rowlist__label { font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); color: var(--text-heading); }
.rowlist__sub { font-size: var(--font-size-xs); color: var(--text-subtle); }
.rowlist__value { font-size: var(--font-size-sm); color: var(--text-table); text-align: end; }

.rowlist__count { flex: none; font-size: 18px; font-weight: var(--font-weight-bold); }
.rowlist__count--red   { color: var(--state-danger); }
.rowlist__count--amber { color: var(--warning-ink); }
.rowlist__count--green { color: var(--brand-primary); }

.rowlist__chev { flex: none; display: flex; }

/* --- priority pills -------------------------------------------------------- */
.pill {
  flex: none;
  display: inline-flex; align-items: center; gap: 6px;
  border-radius: var(--radius-pill);
  padding: 4px 10px;
  font-size: var(--font-size-xs);
  white-space: nowrap;
}
.pill__dot { width: 5px; height: 5px; border-radius: var(--radius-circle); background: currentColor; }
.pill--red   { background: var(--state-danger-soft);  color: var(--state-danger); }
.pill--amber { background: var(--state-warning-soft); color: var(--warning-ink); }
.pill--grey  { background: var(--surface-chip);       color: var(--text-muted); }

@media (max-width: 720px) {
  .hero { padding: 18px; }
  .hero__title { font-size: 24px; }
  .hero__body { align-items: flex-start; }
  .dash__side { max-width: none; }
  .stat { max-width: none; }
}
