/* ==========================================================================
   MyVisit — back-office design system
   Hand-authored CSS. No build step, no external requests, RTL-first.
   Author layout with LOGICAL properties only; `dir="ltr"` needs no overrides.
   --------------------------------------------------------------------------
   1  Tokens            8  Forms            15 Tabs
   2  Theme (dark)      9  Card             16 Pagination
   3  Reset            10  Table            17 Breadcrumb
   4  Base / utils     11  Badge            18 Empty state
   5  App shell        12  Alert            19 Skeleton
   6  Sidebar / topbar 13  Modal            20 Toast / tooltip / avatar
   7  Buttons          14  Dropdown         21 Progress / stat / responsive / print
   ========================================================================== */

/* ==========================================================================
   1 · TOKENS
   ========================================================================== */

:root {
  /* -- palette primitives (theme-invariant) ------------------------------ */
  --brand-50:  #eef4fa;
  --brand-100: #d7e6f3;
  --brand-200: #b2cde3;
  --brand-300: #83aecf;
  --brand-400: #5189b4;
  --brand-500: #2d6d99;
  --brand-600: #1f5880;
  --brand-700: #1a4668;
  --brand-800: #173a55;
  --brand-900: #142f45;

  --neutral-0:   #ffffff;
  --neutral-50:  #f7f8fa;
  --neutral-100: #eef0f4;
  --neutral-200: #e1e5ec;
  --neutral-300: #cbd2dd;
  --neutral-400: #9aa5b6;
  --neutral-500: #6d7889;
  --neutral-600: #505a6b;
  --neutral-700: #3a4452;
  --neutral-800: #252d39;
  --neutral-900: #161c25;
  --neutral-950: #0d1218;

  --green-100: #dcf0e6;
  --green-200: #b3ddc9;
  --green-500: #1f8a63;
  --green-600: #19714f;
  --green-700: #14583e;

  --amber-100: #fbeed4;
  --amber-200: #f2d9a5;
  --amber-500: #9a6a09;
  --amber-600: #7f5607;
  --amber-700: #654405;

  --red-100: #fbe4e2;
  --red-200: #f2c3bf;
  --red-500: #b8302a;
  --red-600: #9a2621;
  --red-700: #7c1e1a;

  --sky-100: #ddeaf7;
  --sky-200: #b7d2ec;
  --sky-500: #1d6296;
  --sky-600: #175079;
  --sky-700: #123f5f;

  /* -- typography -------------------------------------------------------- */
  /* Self-hosted; see public/fonts/fonts.css. The fallbacks only matter for the
     swap window, so they are ordered by metric similarity to Plex Arabic rather
     than by preference. */
  --font-family-base: 'IBM Plex Sans Arabic', 'Segoe UI', 'Noto Sans Arabic', 'Geeza Pro', Tahoma, system-ui, sans-serif;
  --font-family-mono: ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, Consolas, monospace;

  --font-size-2xs:  0.6875rem; /* 11 */
  --font-size-xs:   0.75rem;   /* 12 */
  --font-size-sm:   0.8125rem; /* 13 */
  --font-size-base: 0.875rem;  /* 14 — dense back-office default */
  --font-size-md:   0.9375rem; /* 15 */
  --font-size-lg:   1.0625rem; /* 17 */
  --font-size-xl:   1.25rem;   /* 20 */
  --font-size-2xl:  1.5rem;    /* 24 */
  --font-size-3xl:  1.875rem;  /* 30 */

  --font-weight-regular:  400;
  --font-weight-medium:   500;
  --font-weight-semibold: 600;
  --font-weight-bold:     700;

  --line-height-tight:  1.25;
  --line-height-snug:   1.4;
  --line-height-base:   1.6;
  --letter-spacing-caps: 0.06em;

  /* -- spacing (4px base) ------------------------------------------------ */
  --space-0:  0;
  --space-1:  0.25rem;
  --space-2:  0.5rem;
  --space-3:  0.75rem;
  --space-4:  1rem;
  --space-5:  1.25rem;
  --space-6:  1.5rem;
  --space-8:  2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;

  /* -- radius ------------------------------------------------------------ */
  --radius-xs:     2px;
  --radius-sm:     4px;
  --radius-md:     6px;
  --radius-lg:     10px;
  --radius-xl:     14px;
  --radius-pill:   999px;
  --radius-circle: 50%;

  /* -- shadow (vertical offsets only — direction-neutral) ---------------- */
  --shadow-xs: 0 1px 1px rgba(13, 18, 24, 0.05);
  --shadow-sm: 0 1px 2px rgba(13, 18, 24, 0.07), 0 1px 3px rgba(13, 18, 24, 0.05);
  --shadow-md: 0 2px 6px rgba(13, 18, 24, 0.08), 0 1px 2px rgba(13, 18, 24, 0.06);
  --shadow-lg: 0 8px 24px rgba(13, 18, 24, 0.12), 0 2px 6px rgba(13, 18, 24, 0.07);
  --shadow-xl: 0 18px 48px rgba(13, 18, 24, 0.18);

  /* -- motion ------------------------------------------------------------ */
  --duration-fast: 90ms;
  --duration-base: 140ms;
  --duration-slow: 200ms;
  --ease-standard: cubic-bezier(0.2, 0, 0.38, 1);

  /* -- layout metrics ---------------------------------------------------- */
  --sidebar-width:   15.25rem; /* 244 */
  --topbar-height:   3.5rem;   /* 56  */
  --content-max:     100rem;
  --page-padding:    var(--space-5);
  --tap-target-min:  2.75rem;  /* 44 — enforced hit area, see §4 */
  --control-height-sm: 1.875rem;
  --control-height-md: 2.25rem;
  --control-height-lg: 2.75rem;

  /* -- focus ------------------------------------------------------------- */
  --focus-ring-width:  2px;
  --focus-ring-offset: 2px;

  /* -- z-index ----------------------------------------------------------- */
  --z-base:     0;
  --z-sticky:   100;
  --z-dropdown: 300;
  --z-drawer:   400;
  --z-overlay:  500;
  --z-modal:    600;
  --z-toast:    700;
  --z-tooltip:  800;

  /* -- semantic colour: LIGHT (default) ---------------------------------- */
  --color-bg:              var(--neutral-100);
  --color-bg-subtle:       var(--neutral-50);
  --color-surface:         var(--neutral-0);
  --color-surface-raised:  var(--neutral-0);
  --color-surface-sunken:  var(--neutral-50);
  --color-surface-hover:   var(--neutral-100);
  --color-overlay:         rgba(13, 18, 24, 0.45);

  --color-border:          var(--neutral-200);
  --color-border-strong:   var(--neutral-300);
  --color-border-subtle:   var(--neutral-100);

  --color-text:            var(--neutral-800);
  --color-text-muted:      var(--neutral-600);
  --color-text-subtle:     var(--neutral-500);
  --color-text-inverse:    var(--neutral-0);
  --color-link:            var(--brand-600);
  --color-link-hover:      var(--brand-700);

  --color-primary:         var(--brand-600);
  --color-primary-hover:   var(--brand-700);
  --color-primary-active:  var(--brand-800);
  --color-primary-fg:      var(--neutral-0);
  --color-primary-soft:    var(--brand-50);
  --color-primary-border:  var(--brand-200);

  --color-focus:           var(--brand-500);

  --color-success:         var(--green-600);
  --color-success-fg:      var(--green-700);
  --color-success-soft:    var(--green-100);
  --color-success-border:  var(--green-200);

  --color-warning:         var(--amber-500);
  --color-warning-fg:      var(--amber-700);
  --color-warning-soft:    var(--amber-100);
  --color-warning-border:  var(--amber-200);

  --color-danger:          var(--red-500);
  --color-danger-hover:    var(--red-600);
  --color-danger-fg:       var(--red-700);
  --color-danger-soft:     var(--red-100);
  --color-danger-border:   var(--red-200);

  --color-info:            var(--sky-500);
  --color-info-fg:         var(--sky-700);
  --color-info-soft:       var(--sky-100);
  --color-info-border:     var(--sky-200);

  --color-neutral:         var(--neutral-500);
  --color-neutral-fg:      var(--neutral-700);
  --color-neutral-soft:    var(--neutral-100);
  --color-neutral-border:  var(--neutral-300);

  --color-sidebar-bg:         var(--brand-900);
  --color-sidebar-fg:         #d5e2ee;
  --color-sidebar-fg-muted:   #94aac0;
  --color-sidebar-hover-bg:   rgba(255, 255, 255, 0.07);
  --color-sidebar-active-bg:  rgba(255, 255, 255, 0.12);
  --color-sidebar-active-fg:  var(--neutral-0);
  --color-sidebar-accent:     var(--brand-300);
  --color-sidebar-border:     rgba(255, 255, 255, 0.08);

  --color-topbar-bg:      var(--color-surface);
  --color-table-head-bg:  var(--neutral-50);
  --color-table-stripe:   rgba(13, 18, 24, 0.022);
  --color-table-hover:    var(--brand-50);
  --color-skeleton:       var(--neutral-200);
  --color-code-bg:        var(--neutral-100);
}

/* ==========================================================================
   2 · THEME — dark
   System preference applies unless the user pinned light.
   The explicit [data-theme="dark"] block is declared LAST so a manual
   toggle always wins over the media query at equal specificity.
   ========================================================================== */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --color-bg:              var(--neutral-950);
    --color-bg-subtle:       var(--neutral-900);
    --color-surface:         var(--neutral-900);
    --color-surface-raised:  #1b222c;
    --color-surface-sunken:  #11171f;
    --color-surface-hover:   #222a36;
    --color-overlay:         rgba(0, 0, 0, 0.62);

    --color-border:          #2c3542;
    --color-border-strong:   #3d4856;
    --color-border-subtle:   #212933;

    --color-text:            #e4e9ef;
    --color-text-muted:      #a3afbe;
    --color-text-subtle:     #7e8b9b;
    --color-text-inverse:    var(--neutral-950);
    --color-link:            var(--brand-300);
    --color-link-hover:      var(--brand-200);

    --color-primary:         var(--brand-500);
    --color-primary-hover:   var(--brand-400);
    --color-primary-active:  var(--brand-300);
    --color-primary-fg:      #ffffff;
    --color-primary-soft:    rgba(45, 109, 153, 0.18);
    --color-primary-border:  rgba(83, 137, 180, 0.45);

    --color-focus:           var(--brand-300);

    --color-success:         #35a87c;
    --color-success-fg:      #79d3ac;
    --color-success-soft:    rgba(31, 138, 99, 0.16);
    --color-success-border:  rgba(53, 168, 124, 0.4);

    --color-warning:         #cf9526;
    --color-warning-fg:      #e6bd6c;
    --color-warning-soft:    rgba(207, 149, 38, 0.15);
    --color-warning-border:  rgba(207, 149, 38, 0.4);

    --color-danger:          #d9524b;
    --color-danger-hover:    #e1675f;
    --color-danger-fg:       #f09a94;
    --color-danger-soft:     rgba(217, 82, 75, 0.15);
    --color-danger-border:   rgba(217, 82, 75, 0.4);

    --color-info:            #3f8cc4;
    --color-info-fg:         #86b8dc;
    --color-info-soft:       rgba(63, 140, 196, 0.15);
    --color-info-border:     rgba(63, 140, 196, 0.4);

    --color-neutral:         var(--neutral-400);
    --color-neutral-fg:      #b3bdca;
    --color-neutral-soft:    rgba(154, 165, 182, 0.14);
    --color-neutral-border:  #3d4856;

    --color-sidebar-bg:         #10161e;
    --color-sidebar-fg:         #c3cedb;
    --color-sidebar-fg-muted:   #7b8899;
    --color-sidebar-hover-bg:   rgba(255, 255, 255, 0.05);
    --color-sidebar-active-bg:  rgba(83, 137, 180, 0.2);
    --color-sidebar-active-fg:  #ffffff;
    --color-sidebar-accent:     var(--brand-400);
    --color-sidebar-border:     rgba(255, 255, 255, 0.06);

    --color-topbar-bg:      var(--color-surface);
    --color-table-head-bg:  #1b222c;
    --color-table-stripe:   rgba(255, 255, 255, 0.022);
    --color-table-hover:    rgba(45, 109, 153, 0.13);
    --color-skeleton:       #2c3542;
    --color-code-bg:        #11171f;

    --shadow-xs: 0 1px 1px rgba(0, 0, 0, 0.3);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3);
    --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.45), 0 1px 2px rgba(0, 0, 0, 0.35);
    --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.35);
    --shadow-xl: 0 18px 48px rgba(0, 0, 0, 0.6);

    color-scheme: dark;
  }
}

:root[data-theme='dark'] {
  --color-bg:              var(--neutral-950);
  --color-bg-subtle:       var(--neutral-900);
  --color-surface:         var(--neutral-900);
  --color-surface-raised:  #1b222c;
  --color-surface-sunken:  #11171f;
  --color-surface-hover:   #222a36;
  --color-overlay:         rgba(0, 0, 0, 0.62);

  --color-border:          #2c3542;
  --color-border-strong:   #3d4856;
  --color-border-subtle:   #212933;

  --color-text:            #e4e9ef;
  --color-text-muted:      #a3afbe;
  --color-text-subtle:     #7e8b9b;
  --color-text-inverse:    var(--neutral-950);
  --color-link:            var(--brand-300);
  --color-link-hover:      var(--brand-200);

  --color-primary:         var(--brand-500);
  --color-primary-hover:   var(--brand-400);
  --color-primary-active:  var(--brand-300);
  --color-primary-fg:      #ffffff;
  --color-primary-soft:    rgba(45, 109, 153, 0.18);
  --color-primary-border:  rgba(83, 137, 180, 0.45);

  --color-focus:           var(--brand-300);

  --color-success:         #35a87c;
  --color-success-fg:      #79d3ac;
  --color-success-soft:    rgba(31, 138, 99, 0.16);
  --color-success-border:  rgba(53, 168, 124, 0.4);

  --color-warning:         #cf9526;
  --color-warning-fg:      #e6bd6c;
  --color-warning-soft:    rgba(207, 149, 38, 0.15);
  --color-warning-border:  rgba(207, 149, 38, 0.4);

  --color-danger:          #d9524b;
  --color-danger-hover:    #e1675f;
  --color-danger-fg:       #f09a94;
  --color-danger-soft:     rgba(217, 82, 75, 0.15);
  --color-danger-border:   rgba(217, 82, 75, 0.4);

  --color-info:            #3f8cc4;
  --color-info-fg:         #86b8dc;
  --color-info-soft:       rgba(63, 140, 196, 0.15);
  --color-info-border:     rgba(63, 140, 196, 0.4);

  --color-neutral:         var(--neutral-400);
  --color-neutral-fg:      #b3bdca;
  --color-neutral-soft:    rgba(154, 165, 182, 0.14);
  --color-neutral-border:  #3d4856;

  --color-sidebar-bg:         #10161e;
  --color-sidebar-fg:         #c3cedb;
  --color-sidebar-fg-muted:   #7b8899;
  --color-sidebar-hover-bg:   rgba(255, 255, 255, 0.05);
  --color-sidebar-active-bg:  rgba(83, 137, 180, 0.2);
  --color-sidebar-active-fg:  #ffffff;
  --color-sidebar-accent:     var(--brand-400);
  --color-sidebar-border:     rgba(255, 255, 255, 0.06);

  --color-topbar-bg:      var(--color-surface);
  --color-table-head-bg:  #1b222c;
  --color-table-stripe:   rgba(255, 255, 255, 0.022);
  --color-table-hover:    rgba(45, 109, 153, 0.13);
  --color-skeleton:       #2c3542;
  --color-code-bg:        #11171f;

  --shadow-xs: 0 1px 1px rgba(0, 0, 0, 0.3);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3);
  --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.45), 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.35);
  --shadow-xl: 0 18px 48px rgba(0, 0, 0, 0.6);

  color-scheme: dark;
}

/* ==========================================================================
   3 · RESET
   ========================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  tab-size: 4;
}

body {
  min-block-size: 100vh;
  min-block-size: 100dvh;
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
  line-height: var(--line-height-base);
  color: var(--color-text);
  background-color: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: start;
}

img, svg, video, canvas, iframe { display: block; max-inline-size: 100%; }
img, video { block-size: auto; }

input, button, textarea, select {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

button { background: none; border: 0; }

p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }

h1, h2, h3, h4, h5, h6 {
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}

h1 { font-size: var(--font-size-2xl); }
h2 { font-size: var(--font-size-xl); }
h3 { font-size: var(--font-size-lg); }
h4 { font-size: var(--font-size-md); }
h5, h6 { font-size: var(--font-size-base); }

ul, ol { padding: 0; list-style: none; }

a { color: var(--color-link); text-decoration: none; }
a:hover { color: var(--color-link-hover); text-decoration: underline; }

table { border-collapse: collapse; border-spacing: 0; }

hr {
  block-size: 0;
  border: 0;
  border-block-start: 1px solid var(--color-border);
}

code, kbd, samp, pre { font-family: var(--font-family-mono); font-size: 0.92em; }

code {
  padding-block: 0.1em;
  padding-inline: 0.3em;
  background: var(--color-code-bg);
  border-radius: var(--radius-xs);
}

[hidden] { display: none !important; }

fieldset { padding: 0; border: 0; }
legend { padding: 0; }

::placeholder { color: var(--color-text-subtle); opacity: 1; }

:target { scroll-margin-block-start: calc(var(--topbar-height) + var(--space-4)); }

/* ==========================================================================
   4 · BASE / UTILITIES / A11Y
   ========================================================================== */

/* Visible focus ring on everything interactive. */
:where(a, button, input, select, textarea, summary, [tabindex], [role='button'], [role='tab'], [role='menuitem']):focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus);
  outline-offset: var(--focus-ring-offset);
}

/* Never remove focus for keyboard users; only suppress the legacy always-on ring. */
:focus:not(:focus-visible) { outline: none; }

.sr-only {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  inset-block-start: var(--space-2);
  inset-inline-start: var(--space-2);
  z-index: var(--z-tooltip);
  padding-block: var(--space-2);
  padding-inline: var(--space-4);
  color: var(--color-primary-fg);
  background: var(--color-primary);
  border-radius: var(--radius-sm);
  transform: translateY(-200%);
  transition: transform var(--duration-base) var(--ease-standard);
}
.skip-link:focus { transform: translateY(0); text-decoration: none; }

/* Minimum 44x44 hit area on compact controls without inflating the visual
   density: a transparent overlay extends the target beyond the painted box. */
.tap-safe { position: relative; }
.tap-safe::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-start: 50%;
  block-size: var(--tap-target-min);
  min-inline-size: var(--tap-target-min);
  transform: translateY(-50%);
  pointer-events: auto;
}

/* Coarse pointers get real 44px controls, not just a hit overlay. */
@media (pointer: coarse) {
  :root {
    --control-height-sm: var(--tap-target-min);
    --control-height-md: var(--tap-target-min);
    --control-height-lg: 3rem;
  }

  /* A reference number or a name in a list is the way into a record. On a touch screen its touch area is 44px tall:
     vertical padding on an inline link grows the area that answers a tap without moving a line of text. */
  .table__link { padding-block: 0.8em; }
}

.text-muted   { color: var(--color-text-muted); }
.text-subtle  { color: var(--color-text-subtle); }
.text-danger  { color: var(--color-danger-fg); }
.text-success { color: var(--color-success-fg); }
.text-sm      { font-size: var(--font-size-sm); }
.text-xs      { font-size: var(--font-size-xs); }
.text-start   { text-align: start; }
.text-end     { text-align: end; }
.text-center  { text-align: center; }
.truncate     { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nums         { font-variant-numeric: tabular-nums lining-nums; }
.mono         { font-family: var(--font-family-mono); }
.full         { inline-size: 100%; }

.eyebrow {
  font-size: var(--font-size-2xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--letter-spacing-caps);
  text-transform: uppercase;
  color: var(--color-text-subtle);
}

/* ---- layout primitives ------------------------------------------------- */

.stack { display: flex; flex-direction: column; gap: var(--space-4); }
.stack--xs { gap: var(--space-1); }
.stack--sm { gap: var(--space-2); }
.stack--md { gap: var(--space-3); }
.stack--lg { gap: var(--space-6); }
.stack--xl { gap: var(--space-8); }

.cluster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}
.cluster--xs { gap: var(--space-1); }
.cluster--sm { gap: var(--space-2); }
.cluster--lg { gap: var(--space-5); }
.cluster--between { justify-content: space-between; }
.cluster--end { justify-content: flex-end; }
.cluster--baseline { align-items: baseline; }
.cluster--nowrap { flex-wrap: nowrap; }

.grid { display: grid; gap: var(--space-4); }
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid--auto { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.grid--kpi { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }

@media (max-width: 1100px) {
  .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  .grid--2, .grid--3, .grid--4 { grid-template-columns: minmax(0, 1fr); }
}

.container {
  inline-size: 100%;
  max-inline-size: var(--content-max);
  margin-inline: auto;
}

.divider {
  block-size: 1px;
  background: var(--color-border);
  border: 0;
}

.spacer { flex: 1 1 auto; }

/* ==========================================================================
   5 · APP SHELL
   Grid areas: the sidebar is the first column, so `dir` alone places it on
   the correct edge — no directional rules required.
   ========================================================================== */

.app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas:
    'sidebar topbar'
    'sidebar main';
  min-block-size: 100vh;
  min-block-size: 100dvh;
}

.app-sidebar {
  grid-area: sidebar;
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-sticky);
  display: flex;
  flex-direction: column;
  block-size: 100vh;
  block-size: 100dvh;
  overflow: hidden auto;
  color: var(--color-sidebar-fg);
  background: var(--color-sidebar-bg);
  border-inline-end: 1px solid var(--color-sidebar-border);
  overscroll-behavior: contain;
}

.app-topbar {
  grid-area: topbar;
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: var(--topbar-height);
  padding-inline: var(--page-padding);
  background: var(--color-topbar-bg);
  border-block-end: 1px solid var(--color-border);
}

.app-main {
  grid-area: main;
  min-inline-size: 0;
  padding: var(--page-padding);
}

/* System banners (trial ending, subscription lapsed) sit above the page and
   need their own rhythm — they were butting straight into the first card. */
/* "This is a demonstration" — the platform administrator's banner (with its remove button) and an office's plain note. */
.demo-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  margin-block-end: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-warning, #b7791f);
  border-radius: var(--radius-md, 12px);
  background: color-mix(in srgb, var(--color-warning, #b7791f) 12%, var(--color-surface, #fff));
  color: var(--color-text);
  font-size: var(--font-size-sm);
}
.demo-banner__text { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); flex: 1 1 20rem; }
.demo-banner__confirm { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); flex: 1 1 100%; }
.demo-banner__error { flex: 1 1 100%; color: var(--color-danger, #b3261e); }

.banners {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-block-end: var(--space-5);
}

/* The shell's one place for a refusal the server sends (the plan's limit, a read-only office): above the page's own content. */
[data-refusal] { margin-block-end: var(--space-4); }

.app-scrim {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  background: var(--color-overlay);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--duration-slow) var(--ease-standard), visibility var(--duration-slow);
}

.app-nav-toggle { display: none; }

/* ==========================================================================
   6 · SIDEBAR NAV / TOPBAR
   ========================================================================== */

.sidebar__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: var(--topbar-height);
  padding-inline: var(--space-4);
  color: var(--color-sidebar-active-fg);
  border-block-end: 1px solid var(--color-sidebar-border);
  flex: 0 0 auto;
}
.sidebar__brand:hover { color: var(--color-sidebar-active-fg); text-decoration: none; }

.sidebar__mark {
  display: grid;
  place-items: center;
  inline-size: 1.75rem;
  block-size: 1.75rem;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  color: var(--color-sidebar-active-fg);
  background: var(--brand-600);
  border-radius: var(--radius-sm);
  flex: 0 0 auto;
}

.sidebar__title {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}
.sidebar__subtitle {
  font-size: var(--font-size-2xs);
  color: var(--color-sidebar-fg-muted);
}

.sidebar__scroll { flex: 1 1 auto; padding-block: var(--space-3); }
.sidebar__footer {
  flex: 0 0 auto;
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-2xs);
  color: var(--color-sidebar-fg-muted);
  border-block-start: 1px solid var(--color-sidebar-border);
}

.nav-group + .nav-group { margin-block-start: var(--space-4); }

.nav-group__label {
  padding-block: var(--space-1);
  padding-inline: var(--space-4);
  font-size: var(--font-size-2xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--letter-spacing-caps);
  text-transform: uppercase;
  color: var(--color-sidebar-fg-muted);
}

.nav-list { display: flex; flex-direction: column; }

.nav-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: var(--tap-target-min);
  padding-block: var(--space-2);
  padding-inline: var(--space-4);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-sidebar-fg);
  border-inline-start: 3px solid transparent;
  transition: background-color var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard);
}
.nav-link:hover {
  color: var(--color-sidebar-active-fg);
  background: var(--color-sidebar-hover-bg);
  text-decoration: none;
}
.nav-link.is-active,
.nav-link[aria-current='page'] {
  color: var(--color-sidebar-active-fg);
  background: var(--color-sidebar-active-bg);
  border-inline-start-color: var(--color-sidebar-accent);
}
.nav-link.is-disabled,
.nav-link[aria-disabled='true'] {
  color: var(--color-sidebar-fg-muted);
  cursor: not-allowed;
  opacity: 0.55;
}
.nav-link.is-disabled:hover { background: none; }

.nav-link__icon { flex: 0 0 auto; inline-size: 1.125rem; block-size: 1.125rem; }
.nav-link__label { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.nav-link__badge {
  flex: 0 0 auto;
  min-inline-size: 1.25rem;
  padding-inline: var(--space-1);
  font-size: var(--font-size-2xs);
  font-weight: var(--font-weight-semibold);
  line-height: 1.25rem;
  text-align: center;
  color: var(--color-sidebar-active-fg);
  background: rgba(255, 255, 255, 0.16);
  border-radius: var(--radius-pill);
}

/* ---- topbar ------------------------------------------------------------ */

.topbar__title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.topbar__actions {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-inline-start: auto;
}

.topbar__sep {
  inline-size: 1px;
  block-size: 1.5rem;
  background: var(--color-border);
  margin-inline: var(--space-1);
}

.locale-switch {
  display: inline-flex;
  padding: 2px;
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}
.locale-switch__item {
  padding-block: var(--space-1);
  padding-inline: var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  border-radius: var(--radius-xs);
  transition: background-color var(--duration-fast) var(--ease-standard);
}
.locale-switch__item:hover { color: var(--color-text); text-decoration: none; }
.locale-switch__item.is-active {
  color: var(--color-text);
  background: var(--color-surface);
  box-shadow: var(--shadow-xs);
}

/* ==========================================================================
   7 · BUTTONS
   ========================================================================== */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-block-size: var(--control-height-md);
  padding-block: var(--space-1);
  padding-inline: var(--space-4);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-tight);
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  transition: background-color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard);
}
.btn:hover { text-decoration: none; }

/* 44px minimum hit area without inflating the painted control. */
.btn::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-start: 50%;
  block-size: max(100%, var(--tap-target-min));
  transform: translateY(-50%);
}

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

.btn__icon { flex: 0 0 auto; inline-size: 1.0625rem; block-size: 1.0625rem; }

/* -- variants ------------------------------------------------------------ */

.btn--primary {
  color: var(--color-primary-fg);
  background: var(--color-primary);
  border-color: var(--color-primary);
}
.btn--primary:hover { color: var(--color-primary-fg); background: var(--color-primary-hover); border-color: var(--color-primary-hover); }
.btn--primary:active { background: var(--color-primary-active); border-color: var(--color-primary-active); }

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

.btn--danger {
  color: var(--color-primary-fg);
  background: var(--color-danger);
  border-color: var(--color-danger);
}
.btn--danger:hover { color: var(--color-primary-fg); background: var(--color-danger-hover); border-color: var(--color-danger-hover); }

.btn--ghost {
  color: var(--color-text-muted);
  background: transparent;
  border-color: transparent;
}
.btn--ghost:hover { color: var(--color-text); background: var(--color-surface-hover); }
.btn--ghost.is-active { color: var(--color-text); background: var(--color-surface-hover); }

.btn--link {
  min-block-size: auto;
  padding: 0;
  color: var(--color-link);
  background: none;
  border: 0;
}
.btn--link:hover { color: var(--color-link-hover); text-decoration: underline; }

/* -- sizes --------------------------------------------------------------- */

.btn--sm {
  min-block-size: var(--control-height-sm);
  padding-inline: var(--space-3);
  font-size: var(--font-size-sm);
}
.btn--sm .btn__icon { inline-size: 0.9375rem; block-size: 0.9375rem; }

.btn--lg {
  min-block-size: var(--control-height-lg);
  padding-inline: var(--space-6);
  font-size: var(--font-size-md);
}

.btn--icon {
  inline-size: var(--control-height-md);
  min-inline-size: var(--control-height-md);
  padding-inline: 0;
}
.btn--icon.btn--sm { inline-size: var(--control-height-sm); min-inline-size: var(--control-height-sm); }
.btn--icon.btn--lg { inline-size: var(--control-height-lg); min-inline-size: var(--control-height-lg); }

.btn--block { display: flex; inline-size: 100%; }

/* -- loading ------------------------------------------------------------- */

.btn.is-loading { color: transparent; pointer-events: none; }
.btn.is-loading .btn__icon,
.btn.is-loading > :not(.btn__spinner) { visibility: hidden; }

.btn__spinner {
  position: absolute;
  inline-size: 1rem;
  block-size: 1rem;
  border: 2px solid currentColor;
  border-block-start-color: transparent;
  border-radius: var(--radius-circle);
  color: var(--color-primary-fg);
  visibility: visible;
  animation: spin 640ms linear infinite;
}
.btn--secondary .btn__spinner,
.btn--ghost .btn__spinner { color: var(--color-text); }

@keyframes spin { to { transform: rotate(360deg); } }

/* -- button group -------------------------------------------------------- */

.btn-group { display: inline-flex; }
.btn-group .btn { border-radius: 0; }
.btn-group .btn + .btn { margin-inline-start: -1px; }
.btn-group .btn:first-child {
  border-start-start-radius: var(--radius-sm);
  border-end-start-radius: var(--radius-sm);
}
.btn-group .btn:last-child {
  border-start-end-radius: var(--radius-sm);
  border-end-end-radius: var(--radius-sm);
}
.btn-group .btn:focus-visible { z-index: 1; }

/* ==========================================================================
   8 · FORMS
   ========================================================================== */

.field { display: flex; flex-direction: column; gap: var(--space-1); }
.field + .field { margin-block-start: var(--space-4); }
.stack .field + .field { margin-block-start: 0; }

.field__label {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}

.field__required {
  color: var(--color-danger-fg);
  font-weight: var(--font-weight-bold);
}

.field__optional {
  font-size: var(--font-size-2xs);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-subtle);
}

.field__help {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}

.field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-danger-fg);
}
/* Shape cue so the error is not signalled by colour alone. */
.field__error::before {
  content: '';
  flex: 0 0 auto;
  inline-size: 0.75rem;
  block-size: 0.75rem;
  margin-block-start: 0.28em;
  background: currentColor;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

.input,
.select,
.textarea {
  inline-size: 100%;
  min-block-size: var(--control-height-md);
  padding-block: var(--space-1);
  /* A variable, not a literal, so a theme can retune the inner padding without
     overriding (and silently clobbering) variants that set their own sides —
     the search box reserves room for its icon this way. */
  padding-inline: var(--input-padding-inline, var(--space-3));
  font-size: var(--font-size-base);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  transition: border-color var(--duration-fast) var(--ease-standard),
              box-shadow var(--duration-fast) var(--ease-standard);
}

.input:hover:not(:disabled),
.select:hover:not(:disabled),
.textarea:hover:not(:disabled) { border-color: var(--color-neutral); }

.input:focus,
.select:focus,
.textarea:focus {
  border-color: var(--color-focus);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
  outline: none;
}
.input:focus-visible,
.select:focus-visible,
.textarea:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus);
  outline-offset: 1px;
}

.input:disabled,
.select:disabled,
.textarea:disabled,
.input[readonly] {
  color: var(--color-text-subtle);
  background: var(--color-surface-sunken);
  cursor: not-allowed;
}

.input.is-invalid,
.select.is-invalid,
.textarea.is-invalid,
[aria-invalid='true'].input,
[aria-invalid='true'].select,
[aria-invalid='true'].textarea {
  border-color: var(--color-danger);
  background: var(--color-danger-soft);
}
.input.is-invalid:focus,
.select.is-invalid:focus,
.textarea.is-invalid:focus { box-shadow: 0 0 0 3px var(--color-danger-soft); }

.textarea {
  min-block-size: 5rem;
  padding-block: var(--space-2);
  line-height: var(--line-height-snug);
  resize: vertical;
}

.input--sm, .select--sm { min-block-size: var(--control-height-sm); font-size: var(--font-size-sm); }
.input--lg, .select--lg { min-block-size: var(--control-height-lg); font-size: var(--font-size-md); }
.input--nums { font-variant-numeric: tabular-nums lining-nums; }

/* -- select: caret drawn as a logically-positioned pseudo-element -------- */

.select-wrap { position: relative; display: block; inline-size: 100%; }

.select {
  appearance: none;
  -webkit-appearance: none;
  padding-inline-end: var(--space-8);
  cursor: pointer;
}

.select-wrap::after {
  content: '';
  position: absolute;
  inset-inline-end: var(--space-3);
  inset-block-start: 50%;
  inline-size: 0.5rem;
  block-size: 0.3125rem;
  background: var(--color-text-muted);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  transform: translateY(-50%);
  pointer-events: none;
}

/* -- input with leading/trailing affix ----------------------------------- */

.input-group { display: flex; align-items: stretch; inline-size: 100%; }
.input-group .input { border-radius: 0; }
.input-group > :first-child {
  border-start-start-radius: var(--radius-sm);
  border-end-start-radius: var(--radius-sm);
}
.input-group > :last-child {
  border-start-end-radius: var(--radius-sm);
  border-end-end-radius: var(--radius-sm);
}
.input-group__affix {
  display: inline-flex;
  align-items: center;
  padding-inline: var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border-strong);
  white-space: nowrap;
}
.input-group__affix + .input,
.input + .input-group__affix { margin-inline-start: -1px; }

/* -- checkbox & radio ---------------------------------------------------- */

.choice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  min-block-size: var(--tap-target-min);
  padding-block: var(--space-2);
  cursor: pointer;
}
.choice--inline { display: inline-flex; margin-inline-end: var(--space-4); }

/* Native rendering tinted with accent-color: no encoded SVG asset, no
   pseudo-elements on replaced elements (unsupported in Firefox), and the
   OS high-contrast / forced-colors treatment is preserved. */
.checkbox,
.radio {
  flex: 0 0 auto;
  inline-size: 1.0625rem;
  block-size: 1.0625rem;
  margin: 0;
  margin-block-start: 0.15em;
  accent-color: var(--color-primary);
  cursor: pointer;
}

.checkbox:disabled,
.radio:disabled { cursor: not-allowed; opacity: 0.55; }

/* Larger, easier target for coarse pointers. */
@media (pointer: coarse) {
  .checkbox,
  .radio { inline-size: 1.25rem; block-size: 1.25rem; }
}

.choice__text { display: flex; flex-direction: column; gap: 1px; }
.choice__label { font-size: var(--font-size-base); line-height: var(--line-height-snug); }
.choice__help { font-size: var(--font-size-xs); color: var(--color-text-muted); }

/* -- switch -------------------------------------------------------------- */

.switch {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: 0 0 auto;
  inline-size: 2.25rem;
  block-size: 1.25rem;
  background: var(--color-neutral-border);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background-color var(--duration-base) var(--ease-standard);
}
.switch::before {
  content: '';
  position: absolute;
  inset-block-start: 2px;
  inset-inline-start: 2px;
  inline-size: 1rem;
  block-size: 1rem;
  background: var(--neutral-0);
  border-radius: var(--radius-circle);
  box-shadow: var(--shadow-xs);
  transition: margin-inline-start var(--duration-base) var(--ease-standard);
}
.switch:checked { background: var(--color-primary); }
.switch:checked::before { margin-inline-start: 1rem; }

/* -- fieldset ------------------------------------------------------------ */

.fieldset { border-block-start: 1px solid var(--color-border); padding-block-start: var(--space-4); }
.fieldset__legend {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin-block-end: var(--space-3);
}

.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: var(--space-4); }
.form-grid__full { grid-column: 1 / -1; }

.form-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--color-border);
}

/* ==========================================================================
   9 · CARD
   ========================================================================== */

.card {
  display: flex;
  flex-direction: column;
  min-inline-size: 0;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xs);
}

.card__header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-3);
  padding-inline: var(--space-4);
  border-block-end: 1px solid var(--color-border);
}
.card__heading { min-inline-size: 0; flex: 1 1 auto; }
.card__title {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}
.card__subtitle { font-size: var(--font-size-xs); color: var(--color-text-muted); }
.card__actions { display: flex; align-items: center; gap: var(--space-2); margin-inline-start: auto; }

.card__body { padding: var(--space-4); }
.card__body--flush { padding: 0; }
.card__body--tight { padding: var(--space-3); }

.card__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-3);
  padding-inline: var(--space-4);
  background: var(--color-surface-sunken);
  border-block-start: 1px solid var(--color-border);
  border-end-start-radius: var(--radius-md);
  border-end-end-radius: var(--radius-md);
}

.card--raised { box-shadow: var(--shadow-sm); }
.card--flat { box-shadow: none; }
.card--accent { border-block-start: 2px solid var(--color-primary); }

/* ==========================================================================
   10 · DATA TABLE
   ========================================================================== */

.table-wrap {
  inline-size: 100%;
  max-block-size: var(--table-max-height, none);
  overflow: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overscroll-behavior-inline: contain;
}
.table-wrap--flush { border: 0; border-radius: 0; }

.table {
  inline-size: 100%;
  font-size: var(--font-size-sm);
  text-align: start;
  border-collapse: separate;
  border-spacing: 0;
}

.table caption {
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  text-align: start;
}

.table th,
.table td {
  padding-block: var(--space-3);
  padding-inline: var(--space-3);
  text-align: start;
  vertical-align: middle;
  border-block-end: 1px solid var(--color-border-subtle);
}

.table thead th {
  position: sticky;
  inset-block-start: 0;
  z-index: 2;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.02em;
  color: var(--color-text-muted);
  white-space: nowrap;
  background: var(--color-table-head-bg);
  border-block-end: 1px solid var(--color-border-strong);
}

.table tbody tr { transition: background-color var(--duration-fast) var(--ease-standard); }
.table tbody tr:last-child td { border-block-end: 0; }
.table tbody tr:hover { background: var(--color-table-hover); }
.table tbody tr.is-selected { background: var(--color-primary-soft); }

.table--zebra tbody tr:nth-child(even) { background: var(--color-table-stripe); }
.table--zebra tbody tr:nth-child(even):hover { background: var(--color-table-hover); }

.table--compact th,
.table--compact td { padding-block: var(--space-2); padding-inline: var(--space-2); }

.table--bordered td,
.table--bordered th { border-inline-end: 1px solid var(--color-border-subtle); }
.table--bordered td:last-child,
.table--bordered th:last-child { border-inline-end: 0; }

.table tfoot td {
  font-weight: var(--font-weight-semibold);
  background: var(--color-surface-sunken);
  border-block-start: 1px solid var(--color-border-strong);
}

/* `.table .table__num` as well: `.table th, .table td` (start-aligned) is more specific than the class alone and would win. */
.table__num,
.table .table__num { font-variant-numeric: tabular-nums lining-nums; text-align: end; }
.table__actions,
.table .table__actions { inline-size: 1%; white-space: nowrap; text-align: end; }
.table__check { inline-size: 1%; }

.table__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.table__sort::after {
  content: '';
  inline-size: 0.5rem;
  block-size: 0.3125rem;
  background: currentColor;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  opacity: 0.35;
}
.table__sort[aria-sort='ascending']::after { transform: rotate(180deg); opacity: 1; }
.table__sort[aria-sort='descending']::after { opacity: 1; }

.table__empty { padding-block: var(--space-10); text-align: center; color: var(--color-text-muted); }

.table-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-3);
  padding-inline: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-block-end: 0;
  border-start-start-radius: var(--radius-md);
  border-start-end-radius: var(--radius-md);
}
.table-toolbar + .table-wrap {
  border-start-start-radius: 0;
  border-start-end-radius: 0;
}

/* ==========================================================================
   11 · BADGE / STATUS PILL
   Every variant carries a distinct SHAPE cue, so state is legible without
   colour perception: circle / triangle / octagon / diamond / square.
   ========================================================================== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  max-inline-size: 100%;
  padding-block: 0.15rem;
  padding-inline: var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-snug);
  white-space: nowrap;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
}

.badge__shape {
  flex: 0 0 auto;
  inline-size: 0.5rem;
  block-size: 0.5rem;
  background: currentColor;
}

.badge__icon { flex: 0 0 auto; inline-size: 0.875rem; block-size: 0.875rem; }
.badge__text { overflow: hidden; text-overflow: ellipsis; }

.badge--neutral {
  color: var(--color-neutral-fg);
  background: var(--color-neutral-soft);
  border-color: var(--color-neutral-border);
}
/* square */
.badge--neutral .badge__shape { border-radius: 1px; }

.badge--success {
  color: var(--color-success-fg);
  background: var(--color-success-soft);
  border-color: var(--color-success-border);
}
/* circle */
.badge--success .badge__shape { border-radius: var(--radius-circle); }

.badge--warning {
  color: var(--color-warning-fg);
  background: var(--color-warning-soft);
  border-color: var(--color-warning-border);
}
/* triangle */
.badge--warning .badge__shape { clip-path: polygon(50% 0, 100% 100%, 0 100%); }

.badge--danger {
  color: var(--color-danger-fg);
  background: var(--color-danger-soft);
  border-color: var(--color-danger-border);
}
/* octagon */
.badge--danger .badge__shape {
  clip-path: polygon(30% 0, 70% 0, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0 70%, 0 30%);
}

.badge--info {
  color: var(--color-info-fg);
  background: var(--color-info-soft);
  border-color: var(--color-info-border);
}
/* diamond */
.badge--info .badge__shape { clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }

.badge--solid { border-color: transparent; }
.badge--solid.badge--success { color: var(--color-text-inverse); background: var(--color-success); }
.badge--solid.badge--warning { color: var(--color-text-inverse); background: var(--color-warning); }
.badge--solid.badge--danger  { color: #ffffff; background: var(--color-danger); }
.badge--solid.badge--info    { color: #ffffff; background: var(--color-info); }
.badge--solid.badge--neutral { color: var(--color-text-inverse); background: var(--color-neutral); }

.badge--sm { padding-block: 0; padding-inline: var(--space-1); font-size: var(--font-size-2xs); }
.badge--lg { padding-block: var(--space-1); padding-inline: var(--space-3); font-size: var(--font-size-sm); }
.badge--square { border-radius: var(--radius-sm); }
.badge--count {
  min-inline-size: 1.25rem;
  justify-content: center;
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   12 · ALERT
   ========================================================================== */

.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding-block: var(--space-3);
  padding-inline: var(--space-4);
  font-size: var(--font-size-base);
  border: 1px solid transparent;
  border-inline-start-width: 3px;
  border-radius: var(--radius-md);
}

.alert__marker {
  flex: 0 0 auto;
  inline-size: 0.875rem;
  block-size: 0.875rem;
  margin-block-start: 0.28em;
  background: currentColor;
}
.alert__icon { flex: 0 0 auto; inline-size: 1.125rem; block-size: 1.125rem; margin-block-start: 0.1em; }
.alert__body { flex: 1 1 auto; min-inline-size: 0; }
.alert__title { font-weight: var(--font-weight-semibold); line-height: var(--line-height-snug); }
.alert__message { font-size: var(--font-size-sm); }
.alert__actions { display: flex; gap: var(--space-2); margin-block-start: var(--space-2); }
.alert__dismiss {
  flex: 0 0 auto;
  margin-inline-start: auto;
  color: inherit;
  cursor: pointer;
  opacity: 0.7;
}
.alert__dismiss:hover { opacity: 1; }

.alert--success { color: var(--color-success-fg); background: var(--color-success-soft); border-color: var(--color-success-border); border-inline-start-color: var(--color-success); }
.alert--success .alert__marker { border-radius: var(--radius-circle); }

.alert--warning { color: var(--color-warning-fg); background: var(--color-warning-soft); border-color: var(--color-warning-border); border-inline-start-color: var(--color-warning); }
.alert--warning .alert__marker { clip-path: polygon(50% 0, 100% 100%, 0 100%); }

.alert--danger { color: var(--color-danger-fg); background: var(--color-danger-soft); border-color: var(--color-danger-border); border-inline-start-color: var(--color-danger); }
.alert--danger .alert__marker { clip-path: polygon(30% 0, 70% 0, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0 70%, 0 30%); }

.alert--info { color: var(--color-info-fg); background: var(--color-info-soft); border-color: var(--color-info-border); border-inline-start-color: var(--color-info); }
.alert--info .alert__marker { clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }

.alert--neutral { color: var(--color-neutral-fg); background: var(--color-neutral-soft); border-color: var(--color-neutral-border); border-inline-start-color: var(--color-neutral); }
.alert--neutral .alert__marker { border-radius: 1px; }

/* ==========================================================================
   13 · MODAL
   ========================================================================== */

.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: var(--space-6) var(--space-4);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.modal[hidden] { display: none; }

.modal__backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--color-overlay);
}

.modal__dialog {
  position: relative;
  display: flex;
  flex-direction: column;
  inline-size: 100%;
  max-inline-size: 34rem;
  margin-block: auto;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  animation: modal-in var(--duration-slow) var(--ease-standard);
}
.modal__dialog--sm { max-inline-size: 24rem; }
.modal__dialog--lg { max-inline-size: 48rem; }
.modal__dialog--xl { max-inline-size: 64rem; }

@keyframes modal-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

.modal__header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding-block: var(--space-4);
  padding-inline: var(--space-5);
  border-block-end: 1px solid var(--color-border);
}
.modal__title { flex: 1 1 auto; font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold); }
.modal__close { flex: 0 0 auto; margin-inline-start: auto; }

.modal__body { padding: var(--space-5); overflow-y: auto; }

.modal__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  padding-block: var(--space-4);
  padding-inline: var(--space-5);
  background: var(--color-surface-sunken);
  border-block-start: 1px solid var(--color-border);
  border-end-start-radius: var(--radius-lg);
  border-end-end-radius: var(--radius-lg);
}

/* Native <dialog> support for progressive enhancement. */
dialog.modal__dialog { padding: 0; color: var(--color-text); }
dialog.modal__dialog::backdrop { background: var(--color-overlay); }

/* ==========================================================================
   14 · DROPDOWN / MENU
   ========================================================================== */

.dropdown { position: relative; display: inline-flex; }

.dropdown__menu {
  position: absolute;
  inset-block-start: calc(100% + var(--space-1));
  inset-inline-end: 0;
  z-index: var(--z-dropdown);
  min-inline-size: 12rem;
  max-inline-size: 20rem;
  padding-block: var(--space-1);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}
.dropdown__menu[hidden] { display: none; }
.dropdown__menu--start { inset-inline-end: auto; inset-inline-start: 0; }
.dropdown__menu--up { inset-block-start: auto; inset-block-end: calc(100% + var(--space-1)); }

.dropdown__header {
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  border-block-end: 1px solid var(--color-border);
}
.dropdown__name { font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); }
.dropdown__meta { font-size: var(--font-size-xs); color: var(--color-text-muted); }

.dropdown__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  inline-size: 100%;
  min-block-size: var(--tap-target-min);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-text);
  text-align: start;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-standard);
}
.dropdown__item:hover { color: var(--color-text); background: var(--color-surface-hover); text-decoration: none; }
.dropdown__item.is-active { background: var(--color-primary-soft); }
.dropdown__item--danger { color: var(--color-danger-fg); }
.dropdown__item--danger:hover { color: var(--color-danger-fg); background: var(--color-danger-soft); }
.dropdown__item[aria-disabled='true'] { color: var(--color-text-subtle); cursor: not-allowed; }
.dropdown__item__icon { flex: 0 0 auto; inline-size: 1rem; block-size: 1rem; }

.dropdown__divider { block-size: 1px; margin-block: var(--space-1); background: var(--color-border); }

.dropdown__form { display: block; margin: 0; }

/* ==========================================================================
   15 · TABS
   ========================================================================== */

.tabs {
  display: flex;
  gap: var(--space-1);
  overflow-x: auto;
  border-block-end: 1px solid var(--color-border);
  scrollbar-width: thin;
}

.tabs__tab {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-block-size: var(--tap-target-min);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-muted);
  white-space: nowrap;
  cursor: pointer;
  border-block-end: 2px solid transparent;
  margin-block-end: -1px;
  transition: color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard);
}
.tabs__tab:hover { color: var(--color-text); text-decoration: none; }
.tabs__tab.is-active,
.tabs__tab[aria-selected='true'] {
  color: var(--color-link);
  border-block-end-color: var(--color-primary);
}
.tabs__tab[aria-disabled='true'] { color: var(--color-text-subtle); cursor: not-allowed; }

.tabs--pills { border-block-end: 0; }
.tabs--pills .tabs__tab {
  border-block-end: 0;
  margin-block-end: 0;
  border-radius: var(--radius-sm);
}
.tabs--pills .tabs__tab.is-active,
.tabs--pills .tabs__tab[aria-selected='true'] {
  color: var(--color-link);
  background: var(--color-primary-soft);
}

.tabpanel { padding-block-start: var(--space-4); }
.tabpanel[hidden] { display: none; }

/* ==========================================================================
   16 · PAGINATION
   ========================================================================== */

.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* The list wraps: with many pages it is wider than a phone, and a list that cannot wrap widens the whole page. */
.pagination__list { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); }

.pagination__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: var(--control-height-md);
  min-block-size: var(--control-height-md);
  padding-inline: var(--space-2);
  font-size: var(--font-size-sm);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  transition: background-color var(--duration-fast) var(--ease-standard);
}
.pagination__link:hover { color: var(--color-text); background: var(--color-surface-hover); text-decoration: none; }
.pagination__link.is-active,
.pagination__link[aria-current='page'] {
  color: var(--color-primary-fg);
  background: var(--color-primary);
  border-color: var(--color-primary);
}
.pagination__link.is-disabled,
.pagination__link[aria-disabled='true'] {
  color: var(--color-text-subtle);
  background: var(--color-surface-sunken);
  cursor: not-allowed;
  pointer-events: none;
}
.pagination__gap { padding-inline: var(--space-1); color: var(--color-text-subtle); }
.pagination__summary { font-size: var(--font-size-xs); color: var(--color-text-muted); margin-inline-start: auto; }

/* ==========================================================================
   17 · BREADCRUMB
   ========================================================================== */

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}
.breadcrumb__item { display: inline-flex; align-items: center; gap: var(--space-1); }
.breadcrumb__link { color: var(--color-text-muted); }
.breadcrumb__link:hover { color: var(--color-text); }
.breadcrumb__item[aria-current='page'] { color: var(--color-text); font-weight: var(--font-weight-medium); }

/* The separator is a chevron whose direction follows the writing mode. */
.breadcrumb__item + .breadcrumb__item::before {
  content: '';
  inline-size: 0.3125rem;
  block-size: 0.5rem;
  background: var(--color-text-subtle);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  margin-inline-end: var(--space-1);
}
[dir='rtl'] .breadcrumb__item + .breadcrumb__item::before {
  clip-path: polygon(100% 0, 0 50%, 100% 100%);
}

/* ==========================================================================
   18 · EMPTY STATE
   ========================================================================== */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-12);
  padding-inline: var(--space-6);
  text-align: center;
}
.empty-state__icon {
  display: grid;
  place-items: center;
  inline-size: 3rem;
  block-size: 3rem;
  color: var(--color-text-subtle);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-circle);
}
.empty-state__icon svg { inline-size: 1.5rem; block-size: 1.5rem; }
.empty-state__title { font-size: var(--font-size-md); font-weight: var(--font-weight-semibold); }
.empty-state__message {
  max-inline-size: 30rem;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}
.empty-state__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: center; margin-block-start: var(--space-1); }
.empty-state--compact { padding-block: var(--space-6); }

/* ==========================================================================
   19 · SKELETON
   Opacity pulse rather than a directional shimmer — direction-agnostic and
   less distracting in an all-day tool.
   ========================================================================== */

.skeleton {
  display: block;
  block-size: 0.75rem;
  background: var(--color-skeleton);
  border-radius: var(--radius-xs);
  animation: skeleton-pulse 1.4s ease-in-out infinite;
}
.skeleton--text { block-size: 0.7rem; margin-block: 0.25rem; }
.skeleton--title { block-size: 1rem; inline-size: 40%; }
.skeleton--line-70 { inline-size: 70%; }
.skeleton--line-50 { inline-size: 50%; }
.skeleton--line-30 { inline-size: 30%; }
.skeleton--block { block-size: 5rem; border-radius: var(--radius-sm); }
.skeleton--circle { inline-size: 2rem; block-size: 2rem; border-radius: var(--radius-circle); }
.skeleton--btn { inline-size: 5rem; block-size: var(--control-height-md); border-radius: var(--radius-sm); }

.skeleton-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-3);
  border-block-end: 1px solid var(--color-border-subtle);
}
.skeleton-row > .skeleton { flex: 1 1 auto; }

@keyframes skeleton-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

/* ==========================================================================
   20 · TOAST / TOOLTIP / AVATAR
   ========================================================================== */

.toast-region {
  position: fixed;
  inset-block-end: var(--space-4);
  inset-inline-end: var(--space-4);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  inline-size: min(24rem, calc(100vw - var(--space-8)));
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding-block: var(--space-3);
  padding-inline: var(--space-3);
  font-size: var(--font-size-sm);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-inline-start: 3px solid var(--color-neutral);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  pointer-events: auto;
  animation: toast-in var(--duration-slow) var(--ease-standard);
}
.toast__marker { flex: 0 0 auto; inline-size: 0.75rem; block-size: 0.75rem; margin-block-start: 0.3em; background: currentColor; }
.toast__body { flex: 1 1 auto; min-inline-size: 0; color: var(--color-text); }
.toast__title { font-weight: var(--font-weight-semibold); }
.toast__message { color: var(--color-text-muted); }
.toast__dismiss { flex: 0 0 auto; margin-inline-start: auto; color: var(--color-text-subtle); cursor: pointer; }
.toast__dismiss:hover { color: var(--color-text); }

.toast--success { color: var(--color-success); border-inline-start-color: var(--color-success); }
.toast--success .toast__marker { border-radius: var(--radius-circle); }
.toast--warning { color: var(--color-warning); border-inline-start-color: var(--color-warning); }
.toast--warning .toast__marker { clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.toast--danger { color: var(--color-danger); border-inline-start-color: var(--color-danger); }
.toast--danger .toast__marker { clip-path: polygon(30% 0, 70% 0, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0 70%, 0 30%); }
.toast--info { color: var(--color-info); border-inline-start-color: var(--color-info); }
.toast--info .toast__marker { clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }

@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* -- tooltip: centred with inset-inline:0 + margin-inline:auto so it needs
      no directional rules ------------------------------------------------ */

.has-tooltip { position: relative; }

.has-tooltip::after {
  content: attr(data-tooltip);
  position: absolute;
  inset-block-end: calc(100% + 0.375rem);
  inset-inline: 0;
  z-index: var(--z-tooltip);
  inline-size: max-content;
  max-inline-size: 16rem;
  margin-inline: auto;
  padding-block: var(--space-1);
  padding-inline: var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-snug);
  color: var(--neutral-0);
  background: var(--neutral-800);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--duration-base) var(--ease-standard), visibility var(--duration-base);
}
.has-tooltip:hover::after,
.has-tooltip:focus-visible::after { opacity: 1; visibility: visible; }
.has-tooltip--below::after { inset-block-end: auto; inset-block-start: calc(100% + 0.375rem); }

/* -- avatar -------------------------------------------------------------- */

.avatar {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  inline-size: 2rem;
  block-size: 2rem;
  overflow: hidden;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  line-height: 1;
  color: var(--color-primary-fg);
  background: var(--color-primary);
  border-radius: var(--radius-circle);
  user-select: none;
}
.avatar img { inline-size: 100%; block-size: 100%; object-fit: cover; }
.avatar--xs { inline-size: 1.5rem; block-size: 1.5rem; font-size: var(--font-size-2xs); }
.avatar--sm { inline-size: 1.75rem; block-size: 1.75rem; }
.avatar--lg { inline-size: 2.5rem; block-size: 2.5rem; font-size: var(--font-size-sm); }
.avatar--xl { inline-size: 3.5rem; block-size: 3.5rem; font-size: var(--font-size-lg); }
.avatar--square { border-radius: var(--radius-sm); }
.avatar--muted { color: var(--color-text-muted); background: var(--color-neutral-soft); }

.avatar-stack { display: inline-flex; }
.avatar-stack .avatar + .avatar { margin-inline-start: -0.5rem; box-shadow: 0 0 0 2px var(--color-surface); }

/* ==========================================================================
   21 · PROGRESS / STAT TILE / PAGE HEADER
   ========================================================================== */

.progress {
  inline-size: 100%;
  block-size: 0.375rem;
  overflow: hidden;
  background: var(--color-neutral-soft);
  border-radius: var(--radius-pill);
}
.progress__bar {
  block-size: 100%;
  inline-size: var(--progress-value, 0%);
  background: var(--color-primary);
  border-radius: var(--radius-pill);
  transition: inline-size var(--duration-slow) var(--ease-standard);
}
.progress--lg { block-size: 0.625rem; }
.progress--success .progress__bar { background: var(--color-success); }
.progress--warning .progress__bar { background: var(--color-warning); }
.progress--danger  .progress__bar { background: var(--color-danger); }
.progress--indeterminate .progress__bar { inline-size: 35%; animation: progress-sweep 1.2s ease-in-out infinite alternate; }

@keyframes progress-sweep {
  from { margin-inline-start: 0; }
  to   { margin-inline-start: 65%; }
}

.progress-label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  margin-block-end: var(--space-1);
}

/* -- KPI stat tile ------------------------------------------------------- */

.stat-tile {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xs);
}
a.stat-tile { color: inherit; transition: border-color var(--duration-fast) var(--ease-standard); }
a.stat-tile:hover { border-color: var(--color-primary-border); text-decoration: none; box-shadow: var(--shadow-sm); }

.stat-tile__icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  inline-size: 2.25rem;
  block-size: 2.25rem;
  color: var(--color-primary);
  background: var(--color-primary-soft);
  border-radius: var(--radius-sm);
}
.stat-tile__icon svg { inline-size: 1.125rem; block-size: 1.125rem; }

.stat-tile__body { flex: 1 1 auto; min-inline-size: 0; }

.stat-tile__label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-muted);
}
.stat-tile__value {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  font-variant-numeric: tabular-nums lining-nums;
}
.stat-tile__hint { font-size: var(--font-size-xs); color: var(--color-text-subtle); }

.stat-tile__delta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
}
/* Direction is a shape, never colour alone. */
.stat-tile__delta::before {
  content: '';
  inline-size: 0.5rem;
  block-size: 0.4375rem;
  background: currentColor;
}
.stat-tile__delta--up { color: var(--color-success-fg); }
.stat-tile__delta--up::before { clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.stat-tile__delta--down { color: var(--color-danger-fg); }
.stat-tile__delta--down::before { clip-path: polygon(0 0, 100% 0, 50% 100%); }
.stat-tile__delta--flat { color: var(--color-text-muted); }
.stat-tile__delta--flat::before { block-size: 2px; }

.stat-tile--success .stat-tile__icon { color: var(--color-success); background: var(--color-success-soft); }
.stat-tile--warning .stat-tile__icon { color: var(--color-warning); background: var(--color-warning-soft); }
.stat-tile--danger  .stat-tile__icon { color: var(--color-danger);  background: var(--color-danger-soft); }
.stat-tile--info    .stat-tile__icon { color: var(--color-info);    background: var(--color-info-soft); }

/* -- page header --------------------------------------------------------- */

.page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
  margin-block-end: var(--space-5);
}
.page-header__main { flex: 1 1 20rem; min-inline-size: 0; }
.page-header__title {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}
.page-header__subtitle { font-size: var(--font-size-sm); color: var(--color-text-muted); }
.page-header__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin-inline-start: auto; }
.page-header__breadcrumb { margin-block-end: var(--space-1); }

/* -- icons --------------------------------------------------------------- */

.icon {
  display: inline-block;
  inline-size: 1.25rem;
  block-size: 1.25rem;
  flex: 0 0 auto;
  vertical-align: middle;
}
.icon--xs { inline-size: 0.875rem; block-size: 0.875rem; }
.icon--sm { inline-size: 1rem; block-size: 1rem; }
.icon--lg { inline-size: 1.5rem; block-size: 1.5rem; }
.icon--xl { inline-size: 2rem; block-size: 2rem; }

/* Directional glyphs (chevrons, arrows) mirror with the writing mode. */
[dir='rtl'] .icon--flip { transform: scaleX(-1); }

/* ==========================================================================
   22 · RESPONSIVE — sidebar becomes an off-canvas drawer under 900px.
   The drawer slides via margin-inline-start (a logical property), so it
   opens from the correct edge in both directions with no override.
   ========================================================================== */

@media (max-width: 899px) {
  :root { --page-padding: var(--space-4); }

  .app-shell {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas:
      'topbar'
      'main';
  }

  .app-sidebar {
    grid-area: auto;
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    z-index: var(--z-drawer);
    inline-size: var(--sidebar-width);
    margin-inline-start: calc(-1 * var(--sidebar-width));
    box-shadow: var(--shadow-xl);
    transition: margin-inline-start var(--duration-slow) var(--ease-standard);
  }

  .app-shell.is-nav-open .app-sidebar { margin-inline-start: 0; }
  .app-shell.is-nav-open .app-scrim { opacity: 1; visibility: visible; }

  .app-nav-toggle { display: inline-flex; }

  .topbar__title { font-size: var(--font-size-md); }
  .locale-switch { display: none; }
  .card__footer, .modal__footer { padding-inline: var(--space-4); }
  .modal { padding: var(--space-3); }
  .toast-region { inset-inline: var(--space-3); inline-size: auto; }
}

@media (max-width: 599px) {
  .page-header__actions { inline-size: 100%; margin-inline-start: 0; }
  .btn--responsive .btn__text { display: none; }
  .pagination__summary { inline-size: 100%; margin-inline-start: 0; }
}

/* ==========================================================================
   23 · PRINT — receipts: no chrome, black on white
   ========================================================================== */

@media print {
  @page { margin: 14mm; }

  :root {
    --color-bg: #ffffff;
    --color-surface: #ffffff;
    --color-surface-raised: #ffffff;
    --color-surface-sunken: #ffffff;
    --color-text: #000000;
    --color-text-muted: #000000;
    --color-text-subtle: #333333;
    --color-border: #000000;
    --color-border-strong: #000000;
    --color-border-subtle: #999999;
    --color-table-head-bg: #ffffff;
    --color-table-stripe: transparent;
    --shadow-xs: none; --shadow-sm: none; --shadow-md: none;
    --shadow-lg: none; --shadow-xl: none;
  }

  html, body {
    background: #ffffff !important;
    color: #000000 !important;
    font-size: 11pt;
  }

  .app-sidebar,
  .app-topbar,
  .app-scrim,
  .toast-region,
  .no-print,
  .pagination,
  .tabs,
  .table-toolbar,
  .btn,
  .dropdown,
  .breadcrumb,
  .skip-link { display: none !important; }

  .app-shell {
    display: block;
    min-block-size: auto;
  }
  .app-main { padding: 0; }

  .print-only { display: revert !important; }

  .card,
  .stat-tile {
    border: 1px solid #000000 !important;
    box-shadow: none !important;
    break-inside: avoid;
  }

  /* A table can be longer than a page: its rows stay whole (below), the table itself may break. With
     `break-inside: avoid` a long table jumped to a new page whole. */
  .table-wrap {
    border: 1px solid #000000 !important;
    box-shadow: none !important;
    break-inside: auto;
  }

  .table { font-size: 10pt; }
  .table thead { display: table-header-group; }
  .table tfoot { display: table-footer-group; }
  .table thead th { position: static; background: #ffffff !important; border-block-end: 1px solid #000000 !important; }
  .table tbody tr { break-inside: avoid; }

  .badge { border: 1px solid #000000 !important; background: transparent !important; color: #000000 !important; }

  a { color: #000000 !important; text-decoration: none; }
  a[href^='/']::after { content: ''; }

  .receipt { max-inline-size: none; margin: 0; }
  .receipt__header { border-block-end: 2px solid #000000; padding-block-end: 8pt; margin-block-end: 10pt; }
  .receipt__total { border-block-start: 2px solid #000000; font-weight: var(--font-weight-bold); }
  .page-break { break-after: page; }
}

.print-only { display: none; }

/* ==========================================================================
   24 · REDUCED MOTION
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .skeleton { animation: none; opacity: 0.7; }
}

/* ============================================================================
   BRAND — بنك الخدمات
   ----------------------------------------------------------------------------
   Two colours carry the identity: a deep institutional blue for authority, and
   brass for the single accent. Blue alone reads as "generic enterprise"; the
   brass is what makes the product recognisable at a glance — so it is spent
   sparingly, on the logo dot, focus rings, and one element per screen.
   ========================================================================= */

:root {
  --brass-300: #eacb8f;
  --brass-400: #e0b96a;
  --brass-500: #d4a24c;
  --brass-600: #b8852f;
  --brass-700: #8f6621;

  --ink-700: #16456a;
  --ink-800: #0f3251;
  --ink-900: #0a2238;
  --ink-950: #061725;

  --color-accent:        var(--brass-500);
  --color-accent-strong: var(--brass-600);
  --color-accent-soft:   color-mix(in srgb, var(--brass-500) 14%, transparent);
}

/* ---------------------------------------------------------------- logo ---- */

.logo {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  color: inherit;
  text-decoration: none;
}

.logo__mark { flex: 0 0 auto; display: block; overflow: visible; }

.logo__seal { fill: var(--brand-600); }
.logo__dot  { fill: var(--brass-500); }

/* On a dark field the seal inverts, but the dot keeps its brass — it is the one
   element that identifies the brand, so it never changes colour. */
.logo--on-dark .logo__seal { fill: #fff; }

.logo--mono .logo__seal,
.logo--mono .logo__dot { fill: currentColor; }

.logo__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.logo__name {
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-md);
  line-height: 1.15;
  letter-spacing: -0.015em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.logo__subtitle {
  font-size: var(--font-size-2xs);
  line-height: 1.3;
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar .logo__subtitle { color: var(--color-sidebar-fg-muted); }
.sidebar .logo__seal { fill: #fff; }

/* ========================================================================== */
/* AUTH — split canvas                                                        */
/* -------------------------------------------------------------------------- */
/* A centred card on an empty field says "scaffolding". Offices are choosing   */
/* whether to trust this platform with citizens' identity documents, so the    */
/* sign-in screen does one job beyond collecting a password: it states what    */
/* the product is and why it can be trusted.                                   */
/* ========================================================================== */

.auth-body { background: var(--color-bg); }

.auth-shell {
  min-height: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr;
}

@media (min-width: 60rem) {
  .auth-shell {
    grid-template-rows: 1fr;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
  }
}

/* ---- the form side ---- */

.auth-panel {
  display: flex;
  flex-direction: column;
  padding: var(--space-6) var(--space-5);
  background: var(--color-bg);
}

@media (min-width: 60rem) {
  .auth-panel { padding: var(--space-10) var(--space-12); }
}

.auth-panel__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-block-end: auto;
}

.auth-panel__body {
  width: 100%;
  max-width: 24rem;
  margin: var(--space-10) auto;
}

.auth-panel__foot {
  margin-block-start: auto;
  padding-block-start: var(--space-6);
  font-size: var(--font-size-2xs);
  color: var(--color-text-subtle);
}

.auth-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-end: var(--space-3);
  font-size: var(--font-size-2xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--letter-spacing-caps);
  text-transform: uppercase;
  color: var(--color-accent-strong);
}

.auth-eyebrow::before {
  content: "";
  inline-size: 18px;
  block-size: 2px;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
}

.auth-title {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--color-text);
}

.auth-subtitle {
  margin: 0 0 var(--space-8);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-base);
  color: var(--color-text-muted);
}

.auth-form { display: flex; flex-direction: column; gap: var(--space-5); }

.auth-form__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.auth-form .field__label { font-size: var(--font-size-xs); }

/* Taller controls than the default: this form is the one thing on the page,
   and a 44px minimum is a touch-target floor, not a target. */
.auth-form .input {
  block-size: 3rem;
  border-radius: var(--radius-md);
  font-size: var(--font-size-base);
}

.auth-form .input:focus-visible,
.auth-form .input:focus {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px var(--color-accent-soft);
}

.auth-submit {
  inline-size: 100%;
  block-size: 3rem;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}

/* ---- the brand side ---- */

.auth-canvas {
  position: relative;
  display: none;
  overflow: hidden;
  isolation: isolate;
  padding: var(--space-12);
  color: #fff;
  background:
    radial-gradient(130% 100% at 100% 0%, var(--ink-700) 0%, var(--ink-900) 55%, var(--ink-950) 100%);
}

@media (min-width: 60rem) {
  .auth-canvas { display: flex; flex-direction: column; justify-content: space-between; }
}

/* Geometric tessellation, barely there. Decoration that has to be *noticed*
   is decoration that competes with the form. */
.auth-canvas__pattern {
  position: absolute;
  inset: 0;
  z-index: -1;
  /* An <svg> without explicit sizing falls back to 300x150, which tiles a small
     rectangle in one corner instead of the panel. */
  inline-size: 100%;
  block-size: 100%;
  opacity: 0.10;
  color: var(--brass-300);
  pointer-events: none;
  /* Fade the lattice out toward the reading edge so it never competes with the
     headline sitting on top of it. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 34%, transparent 72%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 34%, transparent 72%);
}

.auth-canvas__glow {
  position: absolute;
  inset-block-start: -18%;
  inset-inline-end: -12%;
  z-index: -1;
  inline-size: 30rem;
  block-size: 30rem;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--brass-500) 22%, transparent) 0%, transparent 68%);
  pointer-events: none;
}

.auth-canvas__lede {
  max-inline-size: 30rem;
  margin-block: auto;
}

.auth-canvas__headline {
  margin: 0 0 var(--space-4);
  font-size: clamp(1.6rem, 2.4vw, 2.15rem);
  font-weight: var(--font-weight-bold);
  line-height: 1.3;
  letter-spacing: -0.02em;
}

.auth-canvas__body {
  margin: 0;
  font-size: var(--font-size-md);
  line-height: 1.75;
  color: color-mix(in srgb, #fff 76%, transparent);
}

.auth-canvas .logo__name { font-size: var(--font-size-lg); }
.auth-canvas .logo__subtitle { color: color-mix(in srgb, #fff 62%, transparent); }

.auth-assurances {
  display: grid;
  gap: var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.auth-assurance {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font-size: var(--font-size-sm);
  line-height: 1.55;
  color: color-mix(in srgb, #fff 82%, transparent);
}

.auth-assurance__icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  inline-size: 2rem;
  block-size: 2rem;
  border-radius: var(--radius-md);
  color: var(--brass-400);
  background: color-mix(in srgb, var(--brass-500) 15%, transparent);
  border: 1px solid color-mix(in srgb, var(--brass-500) 26%, transparent);
}

.auth-assurance strong {
  display: block;
  font-weight: var(--font-weight-semibold);
  color: #fff;
}

/* Compact brand strip that replaces the canvas below the split breakpoint. */
.auth-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  color: #fff;
  background: linear-gradient(135deg, var(--ink-800), var(--ink-950));
}

@media (min-width: 60rem) { .auth-strip { display: none; } }

/* ---- entrance: one staggered sequence, 40ms apart ---- */

@media (prefers-reduced-motion: no-preference) {
  .auth-rise {
    animation: auth-rise 460ms var(--ease-standard) both;
    animation-delay: calc(var(--rise-index, 0) * 55ms);
  }
}

@keyframes auth-rise {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

/* ========================================================================== */
/* INTRO — the mark assembling itself                                         */
/* -------------------------------------------------------------------------- */
/* Once per browser session, not once per page load. This is a tool people use */
/* all day; an animation that replayed on every navigation would stop being a  */
/* first impression by mid-morning and start being an obstacle.                */
/* ========================================================================== */

html.intro-locked, html.intro-locked body { overflow: hidden; }

.intro {
  position: fixed;
  inset: 0;
  z-index: var(--z-toast);
  display: grid;
  place-items: center;
  padding: var(--space-6);
  cursor: pointer;
  background: radial-gradient(125% 95% at 50% 10%, var(--ink-700) 0%, var(--ink-900) 52%, var(--ink-950) 100%);
  transition: opacity 420ms var(--ease-standard), visibility 420ms;
}

.intro[hidden] { display: none; }

.intro.is-leaving { opacity: 0; visibility: hidden; pointer-events: none; }

.intro__stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  text-align: center;
}

.intro__name {
  font-size: clamp(1.9rem, 6vw, 2.75rem);
  font-weight: var(--font-weight-bold);
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: #fff;
}

.intro__tagline {
  display: block;
  margin-block-start: var(--space-3);
  font-size: var(--font-size-sm);
  letter-spacing: 0.02em;
  color: color-mix(in srgb, var(--brass-300) 88%, transparent);
}

.intro__skip {
  position: absolute;
  inset-block-end: var(--space-8);
  font-size: var(--font-size-2xs);
  letter-spacing: var(--letter-spacing-caps);
  text-transform: uppercase;
  color: color-mix(in srgb, #fff 42%, transparent);
}

.intro .logo__seal { fill: #fff; }

/* Sized here rather than by the size prop: a splash mark should scale with the
   viewport, and 108px fixed reads as a favicon on a 1440px screen. */
.intro .logo__mark {
  inline-size: clamp(88px, 13vw, 148px);
  block-size: auto;
}

/* The choreography is a stamp landing: the seal arrives large and tilted, bites
   past its resting size on impact, then settles — and only then does the dot drop
   into place. Motion that says what the mark means, rather than decoration. */
.intro.is-playing .logo__seal,
.intro.is-playing .logo__dot,
.intro.is-playing .intro__name,
.intro.is-playing .intro__tagline,
.intro.is-playing .intro__skip { opacity: 0; }

.intro.is-playing .logo__seal {
  transform-origin: 24px 24px;
  animation: intro-stamp 600ms cubic-bezier(0.2, 0.85, 0.3, 1) 100ms forwards;
}

.intro.is-playing .logo__dot {
  transform-origin: 24px 30.5px;
  animation: intro-drop 420ms cubic-bezier(0.34, 1.56, 0.64, 1) 620ms forwards;
}

.intro.is-playing .intro__name    { animation: intro-lift 460ms var(--ease-standard) 820ms forwards; }
.intro.is-playing .intro__tagline { animation: intro-lift 460ms var(--ease-standard) 960ms forwards; }
.intro.is-playing .intro__skip    { animation: intro-fade 360ms var(--ease-standard) 1260ms forwards; }

@keyframes intro-stamp {
  0%   { opacity: 0; transform: scale(1.5) rotate(-10deg); }
  55%  { opacity: 1; transform: scale(0.93) rotate(2.5deg); }
  100% { opacity: 1; transform: none; }
}

@keyframes intro-drop {
  0%   { opacity: 0; transform: translateY(-14px) scale(0.4); }
  100% { opacity: 1; transform: none; }
}

@keyframes intro-lift {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

@keyframes intro-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Reduced motion: the same composition, delivered whole and held briefly.
   Nothing draws, nothing drops, and nobody is made unwell by a splash screen. */
.intro.is-static .logo__seal,
.intro.is-static .logo__dot,
.intro.is-static .intro__name,
.intro.is-static .intro__tagline,
.intro.is-static .intro__skip {
  opacity: 1;
  transform: none;
  animation: none;
  stroke-dashoffset: 0;
}

@media (prefers-reduced-motion: reduce) {
  .intro.is-playing,
  .intro.is-playing * {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    stroke-dashoffset: 0 !important;
  }
}

/* The locale switcher is a row of single-button forms (POST, never GET).
   `contents` keeps the wrappers out of the layout so the buttons stay one row. */
.locale-switch__form { display: contents; }

.auth-help {
  margin: var(--space-6) 0 0;
  font-size: var(--font-size-xs);
  line-height: 1.6;
  color: var(--color-text-muted);
}

.auth-panel__top-brand { min-width: 0; }

@media (min-width: 60rem) {
  /* The canvas already carries the logo at full size; repeating it in the form
     panel is redundant once both are on screen. */
  .auth-panel__top-brand { display: none; }
}

/* ---- inline text link ---- */

.link {
  color: var(--color-link);
  text-decoration: none;
  font-size: var(--font-size-xs);
  border-radius: var(--radius-xs);
  transition: color var(--duration-fast) var(--ease-standard);
}

.link:hover { color: var(--color-link-hover); text-decoration: underline; }

.link:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus);
  outline-offset: var(--focus-ring-offset);
}

/* ---- password reveal ---- */

.auth-password { position: relative; }

.auth-password__toggle {
  position: absolute;
  inset-inline-end: var(--space-2);
  /* Sits on the control itself, clear of the label above it. */
  inset-block-start: calc(1.5rem + var(--space-1));
  display: grid;
  place-items: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--color-text-subtle);
  background: transparent;
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease-standard),
              background-color var(--duration-fast) var(--ease-standard);
}

.auth-password__toggle:hover {
  color: var(--color-text);
  background: var(--color-surface-hover);
}

.auth-password__toggle.is-revealing { color: var(--color-accent-strong); }

.auth-password__toggle:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus);
  outline-offset: -2px;
}

/* Leave room so a long value never runs under the button. */
.auth-password .input { padding-inline-end: 3rem; }

/* Figures that must line up column to column — money, counts, timers, table cells. */
.table, .stat__value, .stat-tile__value, .input--nums, .mono, .tabular {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ---- KPI grid ----------------------------------------------------------- */

.stat-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
}

.stat__label {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  line-height: 1.3;
  color: var(--color-text-muted);
}

.stat__value {
  margin: 0;
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

/* A badge standing in for a number should not inherit the numeral's weight. */
.stat__value .badge { font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); letter-spacing: 0; }

.text-muted { color: var(--color-text-muted); }

/* ==========================================================================
   25 · OFFICE WORKBENCH
   --------------------------------------------------------------------------
   Everything below exists for the five office screens (citizen list, citizen
   form, citizen profile, document queue, employee list). Nothing here is a
   utility bolted on after the fact: each block names a control the design
   system did not yet have. Logical properties only — these screens are read
   right-to-left far more often than left-to-right.
   ========================================================================== */

/* ---- the counter lookup -------------------------------------------------
   One employee runs this search a few hundred times a day. It is the only
   control on the citizen list that is deliberately larger than the density
   of the rest of the page: finding it must never cost a glance. */

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

.search-hero__control { position: relative; display: block; }

.search-hero__input {
  block-size: 3rem;
  /* Room for the leading glyph and, at the other edge, the busy indicator —
     which also keeps the native search-clear button clear of it. */
  padding-inline-start: 2.75rem;
  padding-inline-end: 3.25rem;
  font-size: var(--font-size-md);
  border-radius: var(--radius-md);
}

.search-hero__icon {
  position: absolute;
  inset-inline-start: var(--space-3);
  inset-block-start: 50%;
  transform: translateY(-50%);
  color: var(--color-text-subtle);
  pointer-events: none;
}

.search-hero__status {
  position: absolute;
  inset-inline-end: var(--space-3);
  inset-block-start: 50%;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  transform: translateY(-50%);
  font-size: var(--font-size-xs);
  color: var(--color-text-subtle);
  pointer-events: none;
}

/* ---- inline busy indicator ---------------------------------------------
   The button spinner is positioned absolutely inside .btn and cannot be
   reused outside one. `spin` is the keyframe already declared in §7. */

.spinner {
  display: inline-block;
  flex: 0 0 auto;
  inline-size: 1rem;
  block-size: 1rem;
  border: 2px solid currentColor;
  border-block-start-color: transparent;
  border-radius: var(--radius-circle);
  animation: spin 640ms linear infinite;
}
.spinner--sm { inline-size: 0.75rem; block-size: 0.75rem; border-width: 1.5px; }

/* ---- filter row ---------------------------------------------------------
   A .cluster sizes flex items from their content, which collapses a <select>
   whose own width is 100%. A grid with a floor gives every filter the same
   predictable width and reflows to one column on a phone. */

.filter-bar {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  align-items: end;
}
.filter-bar__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }

/* ---- the link that opens a row -----------------------------------------
   Table cells full of blue link text read as a wall. The record link keeps
   the body colour and earns its affordance from weight plus hover. */

.table__link { color: var(--color-text); font-weight: var(--font-weight-semibold); }
.table__link:hover,
.table__link:focus-visible { color: var(--color-link-hover); text-decoration: underline; }

/* ---- stat tile used as a filter ----------------------------------------
   The document queue counts are the fastest way into the queue, so they are
   real <button>s: focusable, Enter/Space-activatable, and announced with
   aria-pressed. A div with a click handler would be none of those. */

button.stat-tile {
  inline-size: 100%;
  font: inherit;
  color: inherit;
  text-align: start;
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-standard),
              box-shadow var(--duration-fast) var(--ease-standard);
}
button.stat-tile:hover { border-color: var(--color-primary-border); box-shadow: var(--shadow-sm); }

/* Selected state is a ring plus a checkmark in the markup — never colour alone. */
.stat-tile.is-active,
.stat-tile[aria-pressed='true'] {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 1px var(--color-primary);
}

/* The component renders these as <p>; inside a <button> they are <span>s and
   need to stack. No-op for the <p> version. */
.stat-tile__label,
.stat-tile__value { display: block; }

/* ---- read-only detail list ---------------------------------------------- */

.detail-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
}
.detail-grid__label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-muted);
}
.detail-grid__value { font-size: var(--font-size-base); overflow-wrap: break-word; }

/* ---- record rows (documents, notes) -------------------------------------
   Denser than a card per item, separated rather than boxed, and able to hold
   a full-width disclosure panel that a table row cannot. */

.list-rows { display: flex; flex-direction: column; }

.list-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-block: var(--space-3);
}
.list-row + .list-row { border-block-start: 1px solid var(--color-border-subtle); }
.list-row:first-child { padding-block-start: 0; }
.list-row:last-child { padding-block-end: 0; }

.list-row__body { white-space: pre-line; overflow-wrap: break-word; }

/* ---- disclosure ---------------------------------------------------------
   A rejection has to carry a reason, and the reason field should not occupy
   a row it is not being used on. <details> gives that with no script. */

.disclosure { min-inline-size: 0; }

.disclosure__summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-block-size: var(--control-height-sm);
  padding-block: var(--space-1);
  padding-inline: var(--space-3);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-danger-fg);
  cursor: pointer;
  list-style: none;
  border: 1px solid var(--color-danger-border);
  border-radius: var(--radius-sm);
}
.disclosure__summary::-webkit-details-marker { display: none; }
.disclosure__summary:hover { background: var(--color-danger-soft); }

/* The twisty is a triangle that points along the writing direction when
   closed and downward when open, so the state is a shape, not a colour. */
.disclosure__summary::after {
  content: '';
  inline-size: 0.3125rem;
  block-size: 0.5rem;
  background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}
[dir='rtl'] .disclosure__summary::after { clip-path: polygon(100% 0, 0 50%, 100% 100%); }
.disclosure[open] > .disclosure__summary::after {
  inline-size: 0.5rem;
  block-size: 0.3125rem;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}

.disclosure__panel {
  margin-block-start: var(--space-2);
  padding: var(--space-3);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

/* ---- misc --------------------------------------------------------------- */

/* A file input is not a text input: its button needs the vertical room. */
.input--file { padding-block: var(--space-1); cursor: pointer; }

/* A link inside an alert inherits the alert's colour; the default link blue
   fails contrast on the danger and warning tints. */
.alert a,
.alert__actions .btn--link { color: inherit; text-decoration: underline; }
.alert a:hover,
.alert__actions .btn--link:hover { color: inherit; }

/* The first fieldset in a form follows a heading, not another fieldset, so
   its separator rule would be a stray line under the card header. */
.fieldset--lead { border-block-start: 0; padding-block-start: 0; }

/* ==========================================================================
   26 · DASHBOARD
   --------------------------------------------------------------------------
   Prefix `.dash-`. Two-column card rows that collapse to one, a list of today's
   appointments, and the stage bars. Tokens and logical properties only.
   ========================================================================== */

.dash-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
}

@media (max-width: 900px) {
  .dash-grid { grid-template-columns: minmax(0, 1fr); }
}

.dash-list { display: flex; flex-direction: column; }

.dash-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-3);
  border-block-end: 1px solid var(--color-hairline, var(--color-border-subtle));
}
.dash-row:first-child { padding-block-start: 0; }
.dash-row:last-child { padding-block-end: 0; border-block-end: 0; }

.dash-time {
  min-inline-size: 3.25rem;
  padding-block: var(--space-1);
  padding-inline: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  text-align: center;
  color: var(--color-text);
  background: var(--color-fill, var(--color-surface-sunken));
  border-radius: var(--radius-sm);
}

.dash-row__main { display: flex; flex-direction: column; gap: 2px; min-inline-size: 0; }
.dash-row__main .table__link { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-row__meta { font-size: var(--font-size-xs); color: var(--color-text-muted); }
.dash-row__state { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }

.dash-stages { display: flex; flex-direction: column; gap: var(--space-4); }
.dash-stage .progress-label { margin-block-end: var(--space-1); }
.dash-stage .progress-label strong { color: var(--color-text); }

.dash-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-block-start: var(--space-5);
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--color-hairline, var(--color-border-subtle));
  font-size: var(--font-size-sm);
}

.dash-note { margin-block-start: var(--space-3); }

.dash-facts { display: flex; flex-direction: column; margin: 0; }
.dash-facts > div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-3);
  border-block-end: 1px solid var(--color-hairline, var(--color-border-subtle));
}
.dash-facts > div:first-child { padding-block-start: 0; }
.dash-facts > div:last-child { padding-block-end: 0; border-block-end: 0; }
.dash-facts dt { font-size: var(--font-size-sm); color: var(--color-text-muted); }
.dash-facts dd { margin: 0; }
