/* ─────────────────────────────────────────────────────────────────────────────
   Sanad UI · base

   Everything here reads from tokens.css. No hex, no px, no font name.

   Authored with LOGICAL properties throughout — inline-start, block-end,
   margin-inline — never left/right. Arabic RTL and English LTR are equals
   (README §8), and a stylesheet written in physical directions has to be
   mirrored by hand, which is how RTL layouts drift a little further from their
   LTR counterpart with every change.
   ───────────────────────────────────────────────────────────────────────────── */

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

html,
body {
  margin: 0;
  padding: 0;
  block-size: 100%;
}

body {
  font-family: var(--font-ui);
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);

  /* Arabic at 13px needs every bit of rendering help it can get. */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ── numbers ────────────────────────────────────────────────────────────────
   Latin digits always, in every language (README §8 · D16). Arabic-Indic digits
   are what NewPoint's operators do not use and cannot scan at speed, and the
   dates they read are yyyy/MM/dd. Tabular figures make a column of amounts
   line up on the decimal without any alignment code. */
.amount,
.qty,
input[type='number'],
input[inputmode='decimal'],
td.num,
th.num {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
  direction: ltr;                 /* a number reads left-to-right in both locales */
  text-align: end;
  unicode-bidi: plaintext;
}

/* ── focus ──────────────────────────────────────────────────────────────────
   Visible, always. This application is driven from the keyboard by design
   (docs/02): an operator who cannot see where focus is has lost the plot, and
   the whole speed advantage over a mouse-driven system with it. */
:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 1px;
}

/* Never remove the outline without replacing it. */
:focus:not(:focus-visible) {
  outline: none;
}

/* ── app chrome ─────────────────────────────────────────────────────────────── */

.app {
  display: grid;
  grid-template-columns: var(--w-rail) 1fr;
  grid-template-rows: var(--h-title) 1fr var(--h-status);
  grid-template-areas:
    'rail title'
    'rail main'
    'rail status';
  block-size: 100vh;
  overflow: hidden;
}

.app__rail {
  grid-area: rail;
  background: var(--rail);
  color: var(--rail-text);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-1);
  padding-block: var(--sp-2);
  overflow-y: auto;
  scrollbar-width: none;
}

.app__title {
  grid-area: title;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding-inline: var(--sp-3);
  background: var(--panel);
  border-block-end: 1px solid var(--line);
}

.app__main {
  grid-area: main;
  overflow: auto;
  padding: var(--sp-4);
}

.app__status {
  grid-area: status;
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding-inline: var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  background: var(--panel2);
  border-block-start: 1px solid var(--line);
}

/* ── rail buttons ───────────────────────────────────────────────────────────── */

.rail-btn {
  inline-size: 56px;
  min-block-size: 52px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: var(--sp-1);
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: inherit;
  font-family: inherit;
  font-size: var(--fs-xs);
  cursor: pointer;
  text-decoration: none;
  text-align: center;
  line-height: 1.2;
}

.rail-btn:hover {
  background: rgb(255 255 255 / 8%);
}

.rail-btn--active {
  background: rgb(255 255 255 / 14%);
  color: var(--on-dark);
  font-weight: 600;
}

.rail-btn__glyph {
  font-size: var(--fs-lg);
  opacity: 0.9;
}

/* ── menu ───────────────────────────────────────────────────────────────────── */

.menu {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--sp-4);
  align-items: start;
}

.menu__group {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.menu__heading {
  padding: var(--sp-2) var(--sp-3);
  background: var(--head);
  border-block-end: 1px solid var(--line);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.menu__list {
  margin: 0;
  padding: var(--sp-1);
  list-style: none;
}

.menu__link {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-block-size: var(--h-row);
  padding-inline: var(--sp-2);
  border-radius: var(--radius);
  color: var(--text);
  text-decoration: none;
}

.menu__link:hover {
  background: var(--hover);
}

.menu__code {
  font-family: var(--font-num);
  font-size: var(--fs-xs);
  color: var(--faint);
  margin-inline-start: auto;
}

/* ── states ────────────────────────────────────────────────────────────────
   .state and .alert are components.css's. */


/* .error lived here and was a second, slightly different .alert--bad. Two rules for one idea is
   how two screens end up disagreeing about what an error looks like, so it was renamed at every
   call site rather than aliased. components.css owns alerts. */

/* ── motion ─────────────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── sign-in ────────────────────────────────────────────────────────────────
   Two panels: a dark brand side and the form. Modelled on
   design/prototypes/01-login.html, which the operator review will judge. */

.login {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-block-size: 100vh;
}

@media (max-width: 800px) {
  .login {
    grid-template-columns: 1fr;
  }

  .login__brand {
    display: none;
  }
}

.login__brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  background: var(--rail);
  color: var(--rail-text);

  /* Ledger rules — the paper the product replaces. Drawn in the accent so the
     brand panel says "accounting" without a stock illustration. */
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent 31px,
    rgb(255 255 255 / 6%) 31px,
    rgb(255 255 255 / 6%) 32px
  );
}

/* The lockup on the menu. Sized by height so the mark stays square and the word
   keeps its drawn proportion — BRAND.md forbids stretching either. The 2px deep
   rule under it is the guide's document-header emphasis, used once. */
.menu__brand {
  /* The menu is a grid of cards, so the header has to be told to span it — dropped
     into a single cell it sits at one card's width and the rule under it stops
     short, which reads as a card that lost its contents. */
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  padding-block: var(--sp-3);
  margin-block-end: var(--sp-4);
  border-block-end: 2px solid var(--rail);
}

.menu__logo {
  block-size: 34px;
  inline-size: auto;
  min-inline-size: 120px;
}

.menu__spacer { flex: 1; }

/* A platform action in the brand header — quieter than a menu link, because it is not
   one of this company's screens. */
.menu__platform {
  color: var(--brand);
  font-size: var(--fs-sm);
  text-decoration: none;
}

.menu__platform:hover { color: var(--accent-strong); text-decoration: underline; }


.login__mark {
  /* Clear space around any logo is 25% of its height (BRAND.md), which is what the
     block margin below buys. Square, always: the guide forbids stretching the mark. */
  inline-size: 88px;
  block-size: 88px;
  margin-block-end: var(--sp-3);
}

.login__tagline {
  margin: 0;
  font-size: var(--fs-base);
  opacity: 0.75;
}

.login__form {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-5);
  background: var(--panel);
}

.login__form form {
  inline-size: min(360px, 100%);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.login__title {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-xl);
  font-weight: 600;
}

/* ── fields ────────────────────────────────────────────────────────────────
   The field COMPONENT lives in components.css. What stays here is only what is
   specific to a page or a screen kind. app.css loads after components.css, so
   anything restated here silently overrides the standard -- which is exactly
   what .btn, .field and eleven others were doing until they were removed. */


/* ── buttons ───────────────────────────────────────────────────────────────
   The button component is components.css's. Only page-scoped variants here. */



/* ─────────────────────────────────────────────────────────────────────────────
   Document entry — docs/02 §3.1 and §4.

   Compact density is not a preference here, it is the job: entry screens are
   always 32px rows regardless of the global setting (§4.2). Every rule uses
   logical properties so dir="rtl" and dir="ltr" are the same stylesheet, with
   two deliberate exceptions — numbers and codes stay physically LTR, because
   they read left to right in both scripts (§4.4).
   ───────────────────────────────────────────────────────────────────────────── */

.doc {
    display: flex;
    flex-direction: column;
    block-size: 100%;
    min-block-size: 0;
    outline: none;
}

.doc__bar {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
    background: var(--head);
    border-block-end: 1px solid var(--line);
}

.doc__title { font-size: var(--fs-lg); font-weight: 600; }
.doc__subtitle { color: var(--ink-muted); font-size: var(--fs-sm); }
.doc__spacer { flex: 1; }

.doc__id {
    padding: 2px 6px;
    border: 1px solid var(--line2);
    border-radius: var(--radius);
    color: var(--ink-muted);
    font-size: var(--fs-xs);
}

.doc__mode {
    padding: 2px 8px;
    border-radius: var(--radius);
    background: var(--panel2);
    color: var(--ink-muted);
    font-size: var(--fs-xs);
}

.doc__mode--entry { background: var(--accent-soft); color: var(--accent-strong); }

.doc__posted { color: var(--ok); font-size: var(--fs-sm); font-weight: 500; }

.doc__header {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
    border-block-end: 1px solid var(--line);
    background: var(--panel);
}

.field--inline { flex: 0 0 auto; }
.field--grow { flex: 1 1 22rem; }


/* The grid. A CSS grid rather than a table so the column template can change
   with the screen's configuration without re-emitting the markup. */
.grid {
    flex: 1;
    min-block-size: 0;
    overflow: auto;
    background: var(--panel);
}

.grid__head,
.grid__row {
    display: grid;
    grid-template-columns: 3rem 9rem minmax(10rem, 1fr) 6rem 7rem 5rem 8rem;
    align-items: center;
    min-block-size: var(--h-row, 32px);
    border-block-end: 1px solid var(--line);
}

.grid__head {
    position: sticky;
    inset-block-start: 0;
    z-index: 1;
    background: var(--head);
    font-size: var(--fs-xs);
    font-weight: 500;
    letter-spacing: .06em;
    color: var(--ink-muted);
}

.grid__row--current { background: var(--sel); }

/* ── the document grid — handoff §1.5 ────────────────────────────────────────
   Fourteen columns at the handoff's own widths, and its own template so no
   other grid in the system moves. Below 1080px it scrolls sideways inside its
   own box rather than squeezing: a quantity cell 20px wide is not a cell.

   The two discount columns are conditional on show_discount_percent, so there
   are two templates. Deriving one from the other with a grid-auto-column would
   line the headers up with the wrong cells the moment a screen turns the flag
   off — which is precisely the class of bug the chart on the hub had. */
.grid--doc { overflow-x: auto; }

.grid--doc .grid__head,
.grid--doc .grid__row {
    grid-template-columns:
        34px 132px minmax(180px, 1fr) 58px 68px 60px 82px 62px 74px 90px 76px 100px 130px 34px;
    min-inline-size: 1080px;
}

.grid--doc-plain .grid__head,
.grid--doc-plain .grid__row {
    grid-template-columns:
        34px 132px minmax(180px, 1fr) 58px 68px 60px 82px 90px 76px 100px 130px 34px;
    min-inline-size: 944px;
}

/* The identity columns stay put while the money columns scroll. Without a
   background of their own the rows slide visibly underneath them. */
.grid--doc .grid__cell--seq,
.grid--doc .grid__cell--code,
.grid--doc .grid__cell--name {
    position: sticky;
    background: inherit;
    z-index: 1;
}

.grid--doc .grid__cell--seq  { inset-inline-start: 0; }
.grid--doc .grid__cell--code { inset-inline-start: 34px; }
.grid--doc .grid__cell--name { inset-inline-start: 166px; box-shadow: -1px 0 0 var(--line); }

.grid--doc .grid__head .grid__cell--seq,
.grid--doc .grid__head .grid__cell--code,
.grid--doc .grid__head .grid__cell--name { background: var(--head); }

.grid--doc .grid__row { background: var(--panel); }
.grid--doc .grid__row--current { background: var(--sel); }

.grid__cell--unit,
.grid__cell--store { font-size: var(--fs-xs); color: var(--ink-muted); }

/* What is on the shelf, as a colour AND as a tooltip carrying the number —
   a colour on its own is not a quantity, and not everyone can read it. */
.grid__cell--have { color: var(--ok); }
.grid__cell--low  { color: var(--warn); font-weight: 600; }
.grid__cell--out  { color: var(--bad); font-weight: 600; }

/* The line's own total, weighted so the eye lands on it down the column. */
.grid__cell--sum { background: var(--panel2); font-weight: 600; }
.grid--doc .grid__row--current .grid__cell--sum { background: transparent; }

.grid__cell--note .cell { text-align: start; direction: rtl; }

.grid__drop {
    inline-size: 22px;
    block-size: 22px;
    padding: 0;
    font: inherit;
    color: var(--ink-muted);
    background: none;
    border: 0;
    border-radius: 4px;
    cursor: pointer;
}

.grid__drop:hover { color: var(--bad); background: var(--bad-soft); }

/* The cell an operator is actually typing in, on the active row — the handoff
   asks for the WinForms editing cell, which was unmistakable across a room. */
.grid__row--current .cell:focus {
    outline: 2px solid var(--warn);
    outline-offset: -2px;
    background: var(--warn-soft);
}

.grid__cell {
    padding-inline: var(--sp-2);
    font-size: var(--fs-sm);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Numbers and codes read left-to-right in Arabic too, and align to the end so
   the decimal points line up down the column. */
.grid__cell--num,
.grid__cell--seq,
.grid__cell--code { direction: ltr; text-align: end; }

.grid__cell--seq { color: var(--ink-muted); font-size: var(--fs-xs); }

.cell {
    inline-size: 100%;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    font-variant-numeric: tabular-nums;
    padding: 4px 2px;
    text-align: end;
    direction: ltr;
}

/* A ring, never a fill — the value has to stay readable while the cell is
   current, which a filled background quietly ruins on a dense grid. */
.cell:focus {
    outline: 2px solid var(--brand);
    outline-offset: -2px;
    border-radius: 2px;
}

/* Totals are pinned and never scroll. They are the number the operator watches. */
.doc__totals {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-4);
    padding: var(--sp-2) var(--sp-3);
    border-block-start: 1px solid var(--line2);
    background: var(--panel2);
}

/* The same totals row placed ABOVE its grid rather than beneath it. One screen needs it: the VAT
   statement, where the three figures somebody copies onto a return should not be reached by
   scrolling past a thousand ledger legs. The border flips to the other edge so it still reads as
   attached to the grid it belongs to. */
.doc__totals--lead {
    border-block-start: 0;
    border-block-end: 1px solid var(--line2);
}



/* The key bar shows keys, not just labels, so the shortcut is learned by using
   the mouse once (§3.1). */
.keybar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
    border-block-start: 1px solid var(--line);
    background: var(--head);
    font-size: var(--fs-xs);
    color: var(--ink-muted);
}

.keybar__key { display: flex; align-items: center; gap: 4px; }

.keybar kbd {
    padding: 1px 5px;
    border: 1px solid var(--line2);
    border-block-end-width: 2px;
    border-radius: var(--radius);
    background: var(--panel);
    color: var(--text);
    font-family: var(--font-num);
    font-size: var(--fs-xs);
}

/* The picker. Positioned over the grid rather than beside it: the operator's
   eyes are already on the cell they opened it from. */
.picker {
    position: fixed;
    inset-block-start: 20vh;
    inset-inline: 50%;
    transform: translateX(50%);
    inline-size: min(40rem, 90vw);
    max-block-size: 55vh;
    display: flex;
    flex-direction: column;
    background: var(--panel);
    border: 1px solid var(--line2);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    z-index: 20;
}

.picker__head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
    border-block-end: 1px solid var(--line);
    font-weight: 600;
}

.picker__hint { color: var(--ink-muted); font-size: var(--fs-xs); font-weight: 400; }
.picker__list { margin: 0; padding: 0; list-style: none; overflow: auto; }

.picker__row {
    display: grid;
    grid-template-columns: 8rem 1fr 7rem;
    gap: var(--sp-3);
    align-items: center;
    padding: var(--sp-2) var(--sp-3);
    font-size: var(--fs-sm);
    border-block-end: 1px solid var(--line);
}

.picker__row--current { background: var(--accent-soft); }
.picker__row--empty { display: block; color: var(--ink-muted); text-align: center; }
.picker__code { direction: ltr; text-align: start; color: var(--ink-muted); }
.picker__price { direction: ltr; text-align: end; font-variant-numeric: tabular-nums; }

/* The return panel. Tinted so it reads as a different kind of information from
   the identity band above it — an operator glancing at the screen should be able
   to tell a credit note from an invoice without reading the title. */
.doc__header--return { background: var(--warn-soft); }
.doc__loaded { color: var(--ok); font-size: var(--fs-xs); align-self: center; }

/* The document browser. Same row rhythm as the entry grid on purpose: an
   operator moving between the two should not have to re-find the columns. */
.browse { flex: 1; min-block-size: 0; overflow: auto; background: var(--panel); }

.browse__head,
.browse__row {
    display: grid;
    grid-template-columns: 8rem 9rem 8rem 10rem 1fr;
    align-items: center;
    min-block-size: var(--h-row, 32px);
    padding-inline: var(--sp-3);
    border-block-end: 1px solid var(--line);
    font-size: var(--fs-sm);
}

.browse__head {
    position: sticky;
    inset-block-start: 0;
    background: var(--head);
    font-size: var(--fs-xs);
    font-weight: 500;
    letter-spacing: .06em;
    color: var(--ink-muted);
}

.browse__row--current { background: var(--sel); }
.browse__row--empty { display: block; color: var(--ink-muted); padding-block: var(--sp-4); text-align: center; }
.browse__state { color: var(--ink-muted); font-size: var(--fs-xs); }
.browse .num { direction: ltr; text-align: end; font-variant-numeric: tabular-nums; }

.view__field { display: flex; align-items: baseline; gap: var(--sp-2); }
/* A dialog's tabs. Each is a table the save writes to, so they are structure
   rather than decoration — and they are buttons, so Tab reaches them and
   aria-selected says which is open. */
.picker__tabs {
    display: flex;
    gap: var(--sp-1);
    padding: var(--sp-2) var(--sp-3) 0;
    border-block-end: 1px solid var(--line);
    background: var(--panel);
}

.picker__tab {
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid transparent;
    border-block-end: 0;
    border-start-start-radius: var(--r-badge);
    border-start-end-radius: var(--r-badge);
    background: none;
    font: inherit;
    font-size: var(--fs-sm, var(--fs-xs));
    color: var(--ink-muted);
    cursor: pointer;
    margin-block-end: -1px;
}

.picker__tab:hover { color: var(--text); }
.picker__tab:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

.picker__tab--on {
    border-color: var(--line);
    background: var(--panel2);
    color: var(--brand);
    font-weight: 600;
}

/* Forty fields on one tab need two columns; four fields do not. */
.picker--form { inline-size: min(58rem, 96vw); }
.picker--form .editor {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-2) var(--sp-4);

    /* «بيانات اخرى» is 24 fields. Without this the last four sit below the save
       button and an operator finds them by accident or not at all. */
    max-block-size: min(60vh, 34rem);
    overflow-y: auto;
}

@media (max-width: 720px) {
    .picker--form .editor { grid-template-columns: 1fr; }
}

/* A dialog's own buttons, at its foot. The keys are advertised in the head; this
   is the same two actions for a mouse, which docs/14 §6 requires — a form only a
   keyboard can finish is a form half the operators cannot. */
.picker__actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--sp-2);
    padding: var(--sp-3);
    border-block-start: 1px solid var(--line);
    background: var(--panel2);
}

.picker--wide { inline-size: min(52rem, 94vw); }
.picker__list .browse__row { grid-template-columns: 7rem 8rem 7rem 9rem 1fr; }

/* The master-data screen. Same grid rhythm as document entry, because an
   operator moving between the two should not have to re-learn the shape. */
.entity { display: flex; flex-direction: column; block-size: 100%; min-block-size: 0; outline: none; }

.entity__search {
    display: flex;
    align-items: end;
    gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
    border-block-end: 1px solid var(--line);
    background: var(--panel);
}

.entity__row { display: grid; }

/* A heading that sorts. It is a button so Tab reaches it and a screen reader
   announces aria-sort, but it must look like the heading it replaced — no
   border, no fill, the head row's own type. The arrow keeps its own slot so the
   label does not shift sideways the moment a column is chosen. */
.grid__sort {
    display: flex;
    align-items: center;
    gap: var(--sp-1);
    inline-size: 100%;
    min-inline-size: 0;
    padding-inline: var(--sp-2);
    border: 0;
    background: none;
    font: inherit;
    letter-spacing: inherit;
    color: inherit;
    cursor: pointer;
    text-align: start;
}

.grid__sort > span:first-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.grid__sort:hover { color: var(--text); }
.grid__sort:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.grid__sort--on { color: var(--brand); font-weight: 600; }

.grid__sort-mark {
    inline-size: .75rem;
    flex: none;
    font-size: .625rem;
    line-height: 1;
}

/* Codes and numbers align to the end of their cell, so their heading does too —
   otherwise the label sits at one edge and the column it names at the other. */
.grid__sort.grid__cell--code,
.grid__sort.grid__cell--num { justify-content: flex-end; }

/* The record's history, under the grid — the legacy's status bar. Quiet: it is
   read when somebody asks "who did this", not on every glance, so it must not
   compete with the row the operator is standing on. */
.entity__audit {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2) var(--sp-5);
    padding: var(--sp-2) var(--sp-3);
    border-block-start: 1px solid var(--line);
    background: var(--panel2);
    font-size: var(--fs-xs);
    color: var(--ink-muted);
}

.entity__audit-part { display: flex; align-items: baseline; gap: var(--sp-2); }
.entity__audit-label::after { content: ":"; }
.entity__audit-who { color: var(--text); font-weight: 500; }
.entity__audit-when { direction: ltr; unicode-bidi: isolate; }

/* A switched-off record is shown, not hidden: an operator searching for an item
   that has been disabled needs to find it and be told, not to conclude it never
   existed. */
.entity__row--off { opacity: .55; }
.entity__row--off .grid__cell--name::after { content: " (موقوف)"; color: var(--ink-muted); font-size: var(--fs-xs); }

/* The operators screen (27). Its grid, and the form it opens over the grid. */
.entity__form { flex: 1; min-block-size: 0; overflow: auto; padding: var(--sp-4); }
.entity--operators .grid__head, .entity--operators .grid__row { grid-template-columns: 5rem minmax(10rem, 1fr) minmax(12rem, 1.2fr) 7rem 8rem 10rem; }

/* Standing, said in a word rather than a tick. Three states, not two: an
   operator with no identity row cannot sign in, and that is neither "working"
   nor "stopped" — it is a half-finished creation somebody has to repair, and it
   looks identical to a working operator in every other column. */


.badge--off { background: var(--panel2); color: var(--ink-muted); }


/* Reports. Wider columns than an entry grid because the numbers are larger and
   there are more of them; same row height so the two feel like one system. */
.report { display: flex; flex-direction: column; block-size: 100%; min-block-size: 0; outline: none; }
.report__row { grid-template-columns: 7rem minmax(12rem, 1fr) repeat(6, 8rem); }
.statement__row { grid-template-columns: 8rem 6rem 7rem minmax(12rem, 1fr) 8rem 8rem 9rem; }
.statement__row--opening { background: var(--panel2); font-weight: 500; }

/* Not the accent colour. A trial balance that does not balance is a fault, and
   faults are the one thing that must not be styled per-user (docs/02 §4.3). */
.report__unbalanced { color: var(--bad); font-weight: 600; }

/* Settings. Comfortable density, not compact: these screens are visited rarely
   and read carefully, which is the opposite of an entry grid (docs/02 §4.2). */
.settings { display: flex; flex-direction: column; block-size: 100%; min-block-size: 0; outline: none; }
.settings__body { flex: 1; min-block-size: 0; overflow: auto; padding: var(--sp-4); }

.settings__section {
    max-inline-size: 56rem;
    margin-block-end: var(--sp-5);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--panel);
}

.settings__heading {
    margin: 0;
    padding: var(--sp-2) var(--sp-3);
    border-block-end: 1px solid var(--line);
    background: var(--head);
    font-size: var(--fs-sm);
    font-weight: 600;
}

.settings__field {
    display: grid;
    grid-template-columns: minmax(16rem, 1fr) 16rem;
    gap: var(--sp-3);
    align-items: start;
    padding: var(--sp-3);
    border-block-end: 1px solid var(--line);
}

.settings__field:last-child { border-block-end: 0; }

/* An unsaved change is marked on the row, not only in the title bar. A screen
   with thirty settings needs to show WHICH one is pending. */
.settings__field--dirty { background: var(--warn-soft); }
.settings__field--dirty .settings__label > span:first-child::after { content: " •"; color: var(--warn); }

.settings__label { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-base); }
.settings__help { color: var(--ink-muted); font-size: var(--fs-xs); line-height: 1.6; }
.settings__control { display: flex; align-items: center; }
.settings__control .field__input { inline-size: 100%; }
.settings__control input[type=checkbox] { inline-size: 1.15rem; block-size: 1.15rem; }

.settings__dirty { color: var(--warn); font-size: var(--fs-sm); font-weight: 500; }
.keybar__warning { color: var(--warn); font-weight: 500; }

/* The record editor, over the list it came from. */
.editor { padding: var(--sp-4); overflow: auto; display: flex; flex-direction: column; gap: var(--sp-3); }
.editor__field { display: grid; grid-template-columns: 12rem 1fr; gap: var(--sp-3); align-items: center; }
.editor__required { color: var(--bad); margin-inline-start: 2px; }
.editor input[readonly] { background: var(--sunken); color: var(--ink-muted); }
.picker--confirm { inline-size: min(28rem, 90vw); }

/* Voucher lines: account, name, amount, narration. */
.voucher__row { grid-template-columns: 3rem 9rem minmax(10rem, 1fr) 9rem minmax(10rem, 1fr); }

/* Transfer lines: item, description, quantity, remark. No price column, because
   a transfer does not change what the goods are worth. */
.transfer__row { grid-template-columns: 3rem 9rem minmax(10rem, 1fr) 8rem minmax(10rem, 1fr); }
/* An inbound adjustment states a cost, so its grid has one more column. A modifier rather
   than a sixth track on the base rule: every other stock screen has five, and a template
   with a spare column leaves a gap that reads as a missing field. */
/* The item ledger: eight columns, and the last two are the report's reason for
   existing -- the cost a movement carried and the average it left behind. A row
   that did not move the average is dimmed rather than hidden, because an issue is
   not a mistake. */
/* إدارة المنشآت. Six columns, and a stopped company is dimmed rather than hidden:
   an administrator looking for the one they switched off yesterday needs to see it. */
.tenant__row { grid-template-columns: 8rem minmax(10rem, 1fr) minmax(12rem, 1fr) 8rem 6rem 6rem; }
.tenant__row--stopped { color: var(--ink-muted); }

/* A control that reads as a control without being a button-shaped block in a grid row. */
.linkish {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--brand);
  cursor: pointer;
}

.linkish:hover { color: var(--accent-strong); }

/* رصيد المخزون. Negative stock is marked rather than hidden: it is a real state a
   shop can reach, and a report that quietly shows it as an ordinary number is how it
   stays unnoticed until a count. */
.position__row { grid-template-columns: 9rem minmax(10rem, 1fr) 9rem 8rem 8rem 9rem; }
.position__row--negative { color: var(--bad); }

.ledger__row { grid-template-columns: 7rem 5rem 6rem 6rem 6rem 7rem 7rem 8rem; }
.ledger__row--opening { color: var(--ink-muted); font-style: italic; }
.ledger__row--noncost { color: var(--ink-muted); }

.transfer__row--costed { grid-template-columns: 3rem 9rem minmax(9rem, 1fr) 7rem 8rem minmax(9rem, 1fr); }

/* The browse filters. Tinted like the return panel so a list that is filtered
   never looks like a list that is complete. */
.browse__filters { background: var(--panel2); flex-wrap: wrap; }
.browse__filters .field--inline .field__input { inline-size: 8rem; }

/* ─────────────────────────────────────────────────────────────────────────────
   The printed document.

   A fixed width in millimetres, not a fluid layout: this is a sheet of paper,
   and a page that reflows to the window prints differently on every machine.
   ───────────────────────────────────────────────────────────────────────────── */

.print { padding: var(--sp-4); overflow: auto; block-size: 100%; }
.print__actions { display: flex; align-items: center; gap: var(--sp-3); margin-block-end: var(--sp-4); }

.sheet {
    inline-size: 190mm;
    margin-inline: auto;
    padding: 12mm;
    background: var(--print-paper);
    color: var(--print-ink);
    border: 1px solid var(--line2);
    font-size: 12px;
}

.sheet__head { display: flex; justify-content: space-between; gap: var(--sp-4); border-block-end: 2px solid var(--print-ink); padding-block-end: var(--sp-3); }
.sheet__seller { font-size: 16px; font-weight: 700; }
.sheet__line { color: var(--print-line); margin-block-start: 2px; }
.sheet__title { text-align: end; }
.sheet__title h1 { margin: 0; font-size: 18px; }

.sheet__meta { display: flex; flex-wrap: wrap; gap: var(--sp-4); padding-block: var(--sp-3); border-block-end: 1px solid var(--print-rule); }
.sheet__meta > span { display: flex; gap: var(--sp-2); }
.sheet__label { color: var(--print-label); }

.sheet__lines { inline-size: 100%; border-collapse: collapse; margin-block: var(--sp-3); }
.sheet__lines th, .sheet__lines td { padding: 5px 6px; border-block-end: 1px solid var(--print-rule); text-align: start; }
.sheet__lines th { border-block-end: 1px solid var(--print-ink); font-weight: 600; }
.sheet__lines .num { direction: ltr; text-align: end; font-variant-numeric: tabular-nums; }

.sheet__foot { display: flex; justify-content: space-between; align-items: end; gap: var(--sp-4); }
.sheet__totals { display: flex; flex-direction: column; gap: 4px; min-inline-size: 60mm; }
.sheet__totals > div { display: flex; justify-content: space-between; gap: var(--sp-4); }
.sheet__grand { border-block-start: 2px solid var(--print-ink); padding-block-start: 4px; font-size: 14px; font-weight: 700; }

/* 30mm is about the smallest a phone reliably reads off a printed receipt. */
.sheet__qr img { inline-size: 30mm; block-size: 30mm; }

/* ── a master-data list on paper ──────────────────────────────────────────────
   Shares .sheet with the invoice, because they are the same artefact: a fixed
   width in millimetres, printer colours, no screen furniture. What it adds is a
   letterhead image, a report title, and a table that may run to many pages.
   ─────────────────────────────────────────────────────────────────────────── */

/* Full bleed to the sheet's padding: the letterhead is 2480px wide by design and
   is meant to span the page, not to sit inside a margin the paper already has. */
.sheet--list .sheet__letterhead {
    display: block;
    inline-size: calc(100% + 24mm);
    margin: -12mm -12mm var(--sp-3);
}

.sheet__report-title {
    margin: var(--sp-3) 0 var(--sp-2);
    font-size: 16px;
    font-weight: 700;
    text-align: center;
}

.sheet__narrowed {
    margin-block-end: var(--sp-2);
    text-align: center;
    font-size: 11px;
    color: var(--print-label);
}

.sheet--list .sheet__lines th,
.sheet--list .sheet__lines td { border: 1px solid var(--print-rule); }

/* The heading repeats at the top of every printed page. Without it, page four of
   a customer list is four unlabelled columns of text. */
.sheet--list .sheet__lines thead { display: table-header-group; }
.sheet--list .sheet__lines tfoot { display: table-row-group; }
.sheet--list .sheet__lines tr { break-inside: avoid; }

.sheet__truncated { color: var(--bad); font-weight: 600; }

.sheet__foot--list {
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--sp-2) var(--sp-4);
    margin-block-start: var(--sp-3);
    padding-block-start: var(--sp-2);
    border-block-start: 1px solid var(--print-rule);
    font-size: 11px;
}

@media print {
    /* The shell, the navigation and the buttons are screen furniture. What goes
       on paper is the sheet and nothing else. */
    .app__rail, .app__title, .app__status, .keybar, .no-print { display: none !important; }
    .print { padding: 0; }
    .sheet { inline-size: auto; border: 0; padding: 0; }
    @page { margin: 12mm; }

    /* The sheet loses its padding above, so the letterhead's negative margins
       would pull it off the paper. It is already full width there. */
    .sheet--list .sheet__letterhead { inline-size: 100%; margin: 0 0 var(--sp-3); }

    /* Backgrounds are the point here, not decoration: the heading band and the
       totals band are the tenant's own colours, chosen in screen 165 and printed
       by NewPoint. Browsers drop backgrounds when printing unless told. */
    .sheet--list, .sheet--list * { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
}

/* Menu headings carry the module as well as the category — «المخزون · العمليات».
   The module reads as the stronger of the two because it is what an operator is
   navigating by; the category is the shelf within it. */
.menu__module { color: var(--text); font-weight: 600; }
.menu__sep { color: var(--faint); margin-inline: var(--sp-1); }

/* A statement the screen makes about itself, not a warning. Opening stock touches
   no ledger, and an operator entering figures is reasonably worried that it does. */
.notice {
    padding: var(--sp-2) var(--sp-3);
    border-block-end: 1px solid var(--line);
    background: var(--accent-soft);
    color: var(--text);
    font-size: var(--fs-sm, var(--fs-xs));
}

/* Scoped per screen. Both of these were written as `.entity`, so whichever rule came
   second retyped the other screen's columns as well — the cascade collision that is
   invisible until two screens share a base class. */
.entity--opening .grid__head, .entity--opening .grid__row { grid-template-columns: 7rem minmax(10rem, 1fr) 9rem 7rem 7rem 8rem; }

/* The journal. Five columns, and the difference between the two totals is on
   screen throughout rather than announced at the end — an accountant wants to
   watch an entry close, not be told afterwards that it did not. */
.entity--journal .grid__head, .entity--journal .grid__row { grid-template-columns: 8rem minmax(12rem, 1fr) 9rem 9rem minmax(10rem, 1fr); }
.total--balanced .total__value { color: var(--ok); }

/* Opening account balances. Five columns; the difference is stated and never
   refused, because an opening balance is one-sided by design. */
.entity--opening-balance .grid__head, .entity--opening-balance .grid__row { grid-template-columns: 8rem minmax(12rem, 1fr) 9rem 9rem 9rem; }

/* ── title bar, per the handoff ───────────────────────────────────────────────
   design/reference/design-handoff/README.md § Layout Shell puts the mark, the
   system name and the theme toggle here, on the dark rail colour. The brand's
   reverse mark is the one that belongs on a deep surface (BRAND.md § Logo). */

.app__title {
  background: var(--rail);
  color: var(--on-dark);
  border-block-end: 0;
}

.app__mark {
  block-size: 20px;
  inline-size: auto;
}

.app__name {
  font-size: var(--fs-lg);
  font-weight: 600;
  letter-spacing: 0.01em;
}

.app__spacer {
  margin-inline-start: auto;
}

.title-btn__glyph { font-size: var(--fs-sm); }

.title-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  block-size: 28px;
  padding-inline: 10px;
  border: 1px solid rgb(255 255 255 / 22%);
  border-radius: 5px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--fs-sm);
  cursor: pointer;
}

.title-btn:hover {
  background: rgb(255 255 255 / 10%);
}

/* Never removed on a dark bar: the outline is the only thing telling a keyboard
   user where they are, and --accent on the deep teal is too close to read. */
.title-btn:focus-visible {
  outline: 2px solid var(--on-dark);
  outline-offset: -2px;
}

/* ── status bar ───────────────────────────────────────────────────────────── */

.status__dot {
  color: var(--ok);
  font-size: var(--fs-key);
}

/* ── the credit strip under the invoice header — handoff §1.4 ──────────────── */
/* ما تركتَه — a strip, not a modal. An operator opening an invoice must not be stopped by a
   dialog about lines they abandoned last Tuesday; this says what is waiting and gets out of the
   way. Amber because it is a claim on their attention, not an error. */
.doc__drafts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
    background: var(--warn-soft);
    border-block-end: 1px solid var(--line);
    font-size: var(--fs-xs);
}
.drafts__label { color: var(--warn); font-weight: 600; }
.drafts__item  { display: inline-flex; align-items: center; gap: var(--sp-2); }
.drafts__when  { color: var(--ink-muted); direction: ltr; }

/* تعليق المستند — a checkbox on the document, sitting with the credit strip exactly where the
   handoff puts it. Quiet: it is armed rarely and must not compete with the totals. */
.doc__hold {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-3);
    color: var(--ink-muted);
    font-size: var(--fs-xs);
}
.doc__hold__box { inline-size: 14px; block-size: 14px; accent-color: var(--brand); }
.doc__hold:has(.doc__hold__box:checked) { color: var(--warn); font-weight: 600; }

/* انزال مستند — one line, not a panel. It used to reuse the RETURN panel's markup, so a sales
   invoice wore the amber a credit note wears; that colour is what tells an operator at a glance
   that the document reverses another, and spending it here spends the signal. */
.doc__pull {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
    border-block-end: 1px solid var(--line);
}
.pull__label { color: var(--ink-muted); font-size: var(--fs-xs); }
.pull__hint  { color: var(--ink-muted); font-size: var(--fs-xs); opacity: 0.8; }
.pull__input {
    inline-size: 14ch; padding: 2px 6px;
    font-family: var(--font-num); font-variant-numeric: tabular-nums; direction: ltr;
    color: var(--text); background: var(--panel);
    border: 1px solid var(--line); border-radius: var(--r-field);
}
.pull__input:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }

/* من أدخله ومتى — quieter than the credit strip above it on purpose. This line answers a
   question that is asked about a document occasionally; the credit strip answers one that is
   asked about every customer, every time. Same shelf, different voice. */
.doc__audit {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-4);
    padding: var(--sp-2) var(--sp-3);
    color: var(--ink-muted);
    font-size: var(--fs-xs);
    border-block-end: 1px solid var(--line);
}
.audit__item  { display: inline-flex; align-items: center; gap: var(--sp-2); }
.audit__label { color: var(--ink-muted); opacity: 0.75; }
.doc__audit .num { font-family: var(--font-num); font-variant-numeric: tabular-nums; direction: ltr; }

.doc__credit {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-4);
    padding: var(--sp-2) var(--sp-3);
    background: var(--panel2);
    border-block-end: 1px solid var(--line);
}

.credit { display: inline-flex; align-items: baseline; gap: var(--sp-2); }
.credit__label { font-size: var(--fs-xs); color: var(--ink-muted); }
.credit__value { font-size: var(--fs-sm); font-weight: 600; }

/* Past the limit, and exactly on it. Colour only — the server decides whether the
   post is refused, and a screen that greyed out Save on a rule it half knows would
   stop work the server would have allowed. */
.credit--over .credit__value { color: var(--bad); }
.credit--edge .credit__value { color: var(--warn); }

/* The strip when the lookup failed: same shape, so nothing jumps, and the bad
   colour so it is not read as a figure. */
.doc__credit--off .credit__label { color: var(--bad); }

/* ── the live item bar — handoff §Screens 1.7 ──────────────────────────────
   Nine cells in a row, divided by hairlines, each a label above a value. It sits
   between the grid and the totals because that is where the operator's eye already
   is: they have just keyed an item and are about to key a quantity.

   The handoff asks for a 10.5px label. It does not get one -- the interface
   standard (docs/14 §1) puts the floor for Arabic text at 11px, and that standard
   is later and binding. Half a pixel is not worth an operator squinting at the
   number that tells them whether the part is on the shelf.

   It scrolls sideways rather than wrapping. Nine cells do not fit 1366px, and a bar
   that reflows to two rows moves the totals down every time an item is chosen. */
.itembar {
  display: flex;
  align-items: stretch;
  gap: 0;
  overflow-x: auto;
  padding: var(--sp-2) var(--sp-3);
  background: var(--panel2);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.itembar__cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-inline: var(--sp-3);
  border-inline-end: 1px solid var(--line2);
  white-space: nowrap;
}

.itembar__cell:last-child { border-inline-end: 0; }

/* The part's own name takes what is left, and truncates rather than pushing the
   figures off the end -- the numbers are why the bar exists. */
.itembar__cell--name {
  flex: 1 1 auto;
  min-inline-size: 0;
}

.itembar__cell--name .itembar__value {
  overflow: hidden;
  text-overflow: ellipsis;
}

.itembar__label {
  font-size: var(--fs-xs);
  color: var(--ink-muted);
}

.itembar__value {
  font-size: var(--fs-sm);
  color: var(--text);
  font-weight: 600;
}

/* Nothing on the shelf is the one state on this bar worth a colour: it is the
   difference between promising a customer a part and not. */
.itembar__value--bad { color: var(--bad); }

/* A standing note takes the reserved cell's place, so it is coloured to say that
   something replaced a number rather than merely sitting beside it. */
.itembar__cell--note .itembar__value {
  color: var(--warn);
  max-inline-size: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Cost withheld. Quiet and italic -- it is an absence, and it must not be mistaken
   for a figure at a glance. */
.itembar__cell--denied .itembar__value {
  color: var(--faint);
  font-style: italic;
  font-weight: 400;
}

/* What a picker was filtered BY, and how much survived. Five thousand rows and
   five rows look identical from inside a scroll box, and an operator who typed a
   fragment needs to see that it was used. */
.picker__term {
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--accent-soft);
  color: var(--brand);
  font-size: var(--fs-xs);
}

.picker__count {
  padding: 2px 7px;
  border-radius: var(--r-badge);
  background: var(--panel2);
  color: var(--ink-muted);
  font-size: var(--fs-xs);
}

/* ── the document header — design/app §1.4 ─────────────────────────────────
   Three columns of «* · تسمية · حقل» in one panel. Every metric here is the
   prototype's own: an 84px label column, 26px controls, 12.5px text, 6px/20px
   gaps, 11px/14px padding.

   The label column is FIXED at 84px and left-aligned. Letting it size to its
   content puts every field's input at a different distance from the edge, and
   an operator tabbing down a column then reads a ragged left margin instead of
   a straight one — which is most of why a dense form feels untidy.

   Under 1440px it drops to two columns (docs/14 §2), and on a phone to one. */
.doc__head {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px 20px;
  padding: 11px 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 7px;
}

@media (max-width: 1440px) {
  .doc__head { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  .doc__head { grid-template-columns: 1fr; }
}

.hf {
  display: flex;
  align-items: center;
  gap: 7px;
  min-inline-size: 0;
}

/* The account and the note are the two wide ones: a number plus a company name,
   and a sentence. Everything else fits a third of the row. */
.hf--wide { grid-column: span 2; }

@media (max-width: 900px) {
  .hf--wide { grid-column: span 1; }
}

/* REQUIRED, never error — docs/14 §2. A red border is a mistake that has been
   made; a red star is a field that has to be filled. Confusing the two teaches
   operators to ignore red, and then the real errors go unread.

   The slot is always 8px wide whether or not there is a star in it, so the
   labels line up down the column either way. */
.hf__star {
  inline-size: 8px;
  flex: 0 0 auto;
  font-size: 12px;
  color: transparent;
}

.hf__star--on { color: var(--bad); }

.hf__label {
  inline-size: 84px;
  flex: 0 0 auto;
  font-size: 11.5px;
  color: var(--ink-muted);
  text-align: start;
}

.hf__input {
  flex: 1;
  min-inline-size: 0;
  block-size: 26px;
  padding-inline: 8px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--input);
  color: var(--text);
  font-family: inherit;
  font-size: 12.5px;
}

.hf__input:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: -1px;
}

/* Read-only fields are copyable and out of the tab order — docs/14 §2. The
   panel2 ground is what says "this is an answer, not a question". */
.hf__input[readonly] {
  background: var(--panel2);
  color: var(--ink-muted);
}

/* ── line warnings — design/app §1.5, the grid's flags[] ───────────────────
   They sit in the note column, on the line they are about. An operator scanning
   twenty lines for the one that is wrong should find it on the line, not by
   reading a list underneath and counting back up. */
.flag {
  display: inline-block;
  font-size: 11px;
  padding: 3px 9px;
  border-radius: 4px;
  white-space: nowrap;
  margin-inline-end: 4px;
}

.flag--bad {
  background: var(--bad-soft);
  color: var(--bad);
  border: 1px solid color-mix(in oklab, var(--bad) 40%, transparent);
}

.flag--warn {
  background: var(--warn-soft);
  color: var(--warn);
  border: 1px solid color-mix(in oklab, var(--warn) 40%, transparent);
}

/* The cell that CAUSED the warning, tinted so the eye goes from the badge to the
   number without hunting. Bold as well as coloured: colour alone fails for the
   ~8% of men who cannot separate these two hues. */
.cell--alert {
  color: var(--bad);
  background: var(--bad-soft);
  font-weight: 700;
}

/* ── the invitation row — design/app §1.5 ──────────────────────────────────
   Dashed, quiet, and the full width of the grid. It is what tells an operator
   who has never seen this screen that the grid is where they type, and it names
   both ways in: key the number, or scan the barcode. */
.grid__invite { padding: 6px 8px; }

.grid__invite-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  inline-size: 100%;
  block-size: 30px;
  padding-inline: 10px;
  border: 1px dashed var(--line);
  border-radius: 5px;
  background: none;
  color: var(--faint);
  font-size: 12px;
  font-family: inherit;
  text-align: start;
  cursor: pointer;
}

.grid__invite-btn:hover,
.grid__invite-btn:focus-visible {
  border-color: var(--brand);
  color: var(--brand);
}

/* ── the document footer — design/app §5 ───────────────────────────────────
   The four boxes and their skins are the prototype's own totalBox(): plain ·
   info · ok · accent, and the accent one is FILLED rather than tinted.

   The first version of this row made all four plain and coloured only the due
   figure's text. It read as four labels with one of them shouting. Filled, the
   answer is a solid block the eye lands on before it reads anything — which is
   what an operator reading a total aloud to a customer actually does.

   Scoped to the document footer, never to .total itself: vouchers, transfers
   and reports share that class and none of them has an answer to fill in. */
.doc__totals--doc { align-items: center; }

.doc__totals--doc .total {
  gap: 2px;
  padding: 6px 9px;
  border-radius: 7px;
}

.doc__totals--doc .total__label {
  font-size: var(--fs-sm);
  font-weight: 600;
}

.doc__totals--doc .total__value { font-size: 13px; }

/* الخصم — the accent at a third, so it reads as related to the due figure
   without competing with it. */
.doc__totals--doc .total--info {
  border-color: color-mix(in oklab, var(--brand) 33%, transparent);
  background: var(--accent-soft);
}

/* الضريبة — its own hue, because it is money that is not ours. */
.doc__totals--doc .total--vat {
  border-color: color-mix(in oklab, var(--ok) 40%, transparent);
  background: var(--ok-soft);
}

/* الصافي المستحق — filled, not tinted. The one figure on the screen that is an
   answer rather than a working, and the only element down here that carries the
   accent as a ground. */
.doc__totals--doc .total--due {
  border-color: var(--brand);
  background: var(--brand);
}

.doc__totals--doc .total--due .total__label {
  color: var(--accent-fg);
  opacity: 0.85;
}

.doc__totals--doc .total--due .total__value {
  font-size: 21px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--accent-fg);
}

/* The secondary figures, when asked for. Same row shape, quieter, and beneath
   the four rather than beside them — so the eye still lands on the one number
   that matters first. */
.doc__totals--more {
  border-block-start: 0;
  background: var(--panel);
}

.doc__totals--more .total__value { font-size: var(--fs-sm); color: var(--ink-muted); }
