/* Aloke POS on the web — the till's own look.
   ═════════════════════════════════════════════════════════════════════════
   WHY IT DOES NOT LOAD console-theme.css. That sheet says so itself: «the
   admin/super consoles, the till and the customer pages do not load it and
   keep their own look». A console is read; a till is HIT — by somebody
   standing up, in a hurry, often with a queue watching. The two want opposite
   things from the same brand, so this sheet re-values the tokens rather than
   inheriting a reading layout.

   THE THREE RULES EVERYTHING HERE FOLLOWS:

     1. NOTHING A CASHIER PRESSES IS SMALLER THAN 44px, and the things they
        press hundreds of times a day are bigger than that.
     2. EVERY NUMBER IS TABULAR AND LTR-ISOLATED. Arabic is RTL and a price is
        not; a column of prices that shifts by a pixel per digit is a column
        nobody can scan, and «36.00 ر.س» rendered without isolation puts the
        currency on the wrong side of the amount.
     3. THE TICKET IS ALWAYS VISIBLE. Every register layout keeps the running
        total on screen at every width — a total you have to scroll to is a
        total that gets read wrong.

   IT IS BUILT FOR A 1366×768 WINDOWS TILL FIRST, which is the machine the
   founder actually named, and reflows down to a tablet. Below 900px the
   ticket becomes a bottom sheet rather than a column, because a 40 %-width
   ticket on a narrow screen leaves no room for the thing being sold. */

:root {
  --bg: #F6F4FA;
  --surface: #FFFFFF;
  --surface-2: #FBFAFE;
  --ink: #1E1729;
  --muted: #6B6379;
  --line: #E7E2F0;
  --line-strong: #D6CEE6;

  --accent: #5B2C91;
  --accent-press: #43206B;
  --accent-weak: #F2ECFA;
  --accent-ink: #FFFFFF;

  --ok: #1B7A4B;
  --ok-weak: #E8F6EE;
  --warn: #96591A;
  --warn-weak: #FDF3E4;
  --bad: #A3242B;
  --bad-weak: #FCECEC;

  --r-card: 14px;
  --r-btn: 10px;
  --r-pill: 999px;

  --shadow: 0 1px 2px rgba(30, 23, 41, .05), 0 6px 18px rgba(30, 23, 41, .06);
  --shadow-lift: 0 10px 34px rgba(30, 23, 41, .16);
  --ring: 0 0 0 3px rgba(91, 44, 145, .18);

  --rail: 176px;
  --topbar: 60px;

  --font: "Readex Pro", system-ui, -apple-system, "Segoe UI", Tahoma, sans-serif;
  --num: "Inter", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--bg); color: var(--ink);
  font-family: var(--font);
  font-size: 15px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* A till is not a document. Rubber-banding the whole page while a cashier
     drags a long product list is how a tap lands on the wrong row. */
  overscroll-behavior: none;
}

.hidden { display: none !important; }

/* NUMBERS. Applied by class, never inherited: an Arabic name inside an LTR
   isolate would be laid out backwards. */
.num, .money, td.num, .ticket-total b, .stat-num {
  font-family: var(--num);
  font-variant-numeric: tabular-nums;
  direction: ltr; unicode-bidi: isolate;
}

/* ══════════════════════════════════════════════════════════════ shell */

#posShell { display: grid; grid-template-rows: var(--topbar) 1fr; height: 100dvh; }

.pos-top {
  display: flex; align-items: center; gap: 12px;
  padding: 0 14px; background: var(--surface);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 0 rgba(30, 23, 41, .03);
}
/* THE CORNER. The rail's purple runs up through the header for exactly the
   rail's width, so the two are one piece of chrome and not a white bar laid
   across a purple column. The 1px overhang covers the header's own bottom
   border, which would otherwise draw a hairline seam across the block. */
.pos-brand {
  display: flex; align-items: center; gap: 10px; flex: none;
  width: var(--rail); height: calc(100% + 1px); position: relative;
  margin-inline-start: -14px; padding-inline-start: 14px;
  background: linear-gradient(180deg, #57298F 0%, #4E2682 100%);
  color: #fff;
}
.pos-brand .mark {
  width: 32px; height: 32px; border-radius: 8px; flex: none;
  background: rgba(255, 255, 255, .16);
  display: grid; place-items: center; color: #fff; font-weight: 700;
}
.pos-brand h1 {
  font-size: 15px; margin: 0; font-weight: 600; letter-spacing: -.01em;
  color: #fff; white-space: nowrap;
}
.pos-top .spacer { flex: 1; }

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 34px; padding: 4px 12px; border-radius: var(--r-pill);
  background: var(--accent-weak); color: var(--accent-press);
  font-size: 13px; font-weight: 500; white-space: nowrap;
  border: 1px solid transparent;
}
.chip.warn { background: var(--warn-weak); color: var(--warn); }
.chip.bad  { background: var(--bad-weak);  color: var(--bad); }
.chip.ok   { background: var(--ok-weak);   color: var(--ok); }
.chip.mute { background: var(--surface-2); color: var(--muted); border-color: var(--line); }
.chip .dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }

/* A standing condition, not an event — so it is a bar the screen makes room
   for, never a toast that scrolls away while the cashier is looking elsewhere. */
.warnbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 10px; padding: 10px 14px;
  background: var(--warn-weak); color: var(--warn);
  border: 1px solid color-mix(in srgb, var(--warn) 26%, transparent);
  border-radius: 10px; font-size: 14px; line-height: 1.5;
}
.warnbar .note { margin: 0; color: inherit; opacity: .85; }
.warnbar button { margin-inline-start: auto; }
button.chip { cursor: pointer; font-family: inherit; }
button.chip:hover { filter: brightness(.97); }

/* A CHOSEN CHIP HAS TO LOOK CHOSEN — and until this rule existed it did not.
   `aria-pressed` was set correctly on every order-type and payment-method chip
   and styled NOWHERE outside `.reg-sections`, so the pay screen's two most
   consequential choices rendered byte-identically whether or not they were
   selected. Caught by comparing the computed backgrounds of a pressed and an
   unpressed chip, because at a glance both simply look like chips. */
button.chip[aria-pressed="true"] {
  background: var(--accent); color: var(--accent-ink); font-weight: 600;
  border-color: var(--accent-press);
}
button.chip[aria-pressed="true"]:hover { background: var(--accent-press); filter: none; }
button.chip:disabled { opacity: .42; cursor: not-allowed; }

.pos-body { display: grid; grid-template-columns: var(--rail) 1fr; min-height: 0; }

/* THE RAIL IS CHROME, AND IT HAS TO LOOK LIKE IT.
 *
 * It was pure white — the same colour as the product cards it sits beside — so
 * it read as one more panel of content rather than as the frame around it. The
 * Aloke purple fixes that in one move and does two other things for free: an
 * icon inheriting `currentColor` turns white without a rule, and a selected row
 * can be told from an unselected one across a counter, which a pale lilac fill
 * on white could not manage.
 *
 * AND IT HAD TO FIT. Fifteen entries at 44px overflowed a 1366×768 till by
 * 57px with no scroll affordance — «الإعدادات», «الأجهزة» and «الموظفون» simply
 * below the fold on the machine pos.css names as the target, with nothing on
 * screen to say so. The row height is NOT what gave way (nothing a cashier
 * presses goes under 44px); the first group's heading did. See `POS.render`.
 */
.pos-rail {
  background: linear-gradient(180deg, #4E2682 0%, #3A1A5E 100%);
  padding: 10px 8px 14px;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 1px;
  /* The scrollbar is the only thing here that would draw a light-mode
     scrollbar over a dark ground. */
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .28) transparent;
}
.pos-rail::-webkit-scrollbar { width: 6px; }
.pos-rail::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .28); border-radius: 3px;
}

.pos-rail button {
  display: flex; align-items: center; gap: 10px; width: 100%;
  min-height: 44px; padding: 6px 12px; border: 0; border-radius: 9px;
  background: transparent; color: rgba(255, 255, 255, .78);
  font: inherit; font-size: 14px; cursor: pointer; text-align: start;
  /* THE INDICATOR IS ALWAYS THERE, transparent until selected — so a row does
     not shift sideways by 3px when it becomes the current one. */
  border-inline-start: 3px solid transparent;
  transition: background-color .12s ease, color .12s ease;
}
.pos-rail button > span.label {
  /* A LABEL NEVER WRAPS TO A SECOND LINE. «الأصناف والقائمة» is the longest and
     an uneven row in a list of fifteen is what makes a rail look unconsidered;
     the full text is on the button's `title` for anyone who needs it. */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.pos-rail button:hover { background: rgba(255, 255, 255, .09); color: #fff; }
.pos-rail button[aria-current="true"] {
  background: rgba(255, 255, 255, .16);
  color: #fff; font-weight: 600;
  border-inline-start-color: #C9A9FF;
}
.pos-rail button:focus-visible { outline: 2px solid #C9A9FF; outline-offset: -2px; }

.pos-rail .rail-group {
  font-size: 10.5px; color: rgba(255, 255, 255, .5); letter-spacing: .08em;
  padding: 14px 12px 6px; font-weight: 600;
  margin-top: 6px; border-top: 1px solid rgba(255, 255, 255, .14);
}
.pos-rail .rail-badge {
  margin-inline-start: auto; min-width: 22px; padding: 0 6px; height: 20px;
  border-radius: var(--r-pill); background: #FF6B6B; color: #3A1A5E;
  font-size: 11px; font-weight: 700; display: grid; place-items: center;
  font-family: var(--num); font-variant-numeric: tabular-nums;
}

.pos-main { min-width: 0; min-height: 0; overflow: auto; padding: 16px; }
.pos-main.flush { padding: 0; overflow: hidden; }

/* ══════════════════════════════════════════════════════════ primitives */

.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); box-shadow: var(--shadow); padding: 16px;
}
.card + .card { margin-top: 14px; }
.card > h2 { font-size: 17px; margin: 0 0 4px; font-weight: 600; }
.card > .sub { color: var(--muted); font-size: 13.5px; margin: 0 0 14px; }

.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.row.end { justify-content: flex-end; }
.grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.grid3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; }

label.field { display: block; margin-bottom: 12px; }
label.field > span { display: block; font-size: 13px; color: var(--muted); margin-bottom: 5px; }

input, select, textarea {
  width: 100%; min-height: 44px; padding: 8px 12px;
  border: 1px solid var(--line-strong); border-radius: var(--r-btn);
  background: var(--surface); color: var(--ink); font: inherit; font-size: 15px;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: var(--ring);
}
input[type="checkbox"] { width: 20px; height: 20px; min-height: 0; accent-color: var(--accent); }
textarea { min-height: 84px; resize: vertical; }
input[inputmode="decimal"], input.num { font-family: var(--num); direction: ltr; text-align: start; }
input:disabled, select:disabled, button:disabled { opacity: .55; cursor: not-allowed; }

button {
  font-family: inherit; font-size: 15px; cursor: pointer;
  border-radius: var(--r-btn); min-height: 44px; padding: 8px 18px;
  border: 1px solid transparent; background: var(--surface-2); color: var(--ink);
}
button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
button.primary { background: var(--accent); color: var(--accent-ink); font-weight: 600; }
button.primary:hover:not(:disabled) { background: var(--accent-press); }
button.ghost { background: transparent; border-color: var(--line-strong); }
button.ghost:hover:not(:disabled) { background: var(--surface-2); }
button.danger { background: var(--bad); color: #fff; font-weight: 600; }
button.link { background: none; border: 0; color: var(--accent); padding: 4px 6px; min-height: 34px; }
button.sm { min-height: 36px; padding: 4px 12px; font-size: 14px; }
button:active:not(:disabled) { transform: translateY(1px); }

table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
th { text-align: start; font-weight: 600; color: var(--muted); font-size: 13px;
     padding: 8px 10px; border-bottom: 1px solid var(--line); white-space: nowrap; }
td { padding: 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
tbody tr:hover { background: var(--surface-2); }
td.num, th.num { text-align: end; }
.table-wrap { overflow-x: auto; }

.empty { color: var(--muted); text-align: center; padding: 34px 16px; font-size: 14.5px; }
.err  { color: var(--bad); background: var(--bad-weak); border-radius: var(--r-btn);
        padding: 10px 12px; margin: 10px 0; font-size: 14px; }
.ok   { color: var(--ok);  background: var(--ok-weak);  border-radius: var(--r-btn);
        padding: 10px 12px; margin: 10px 0; font-size: 14px; }
.note { color: var(--muted); font-size: 13.5px; }

/* A REFUSAL THE SERVER NAMED. `X-POS-Reason` is a machine word and it is shown
   in a monospace pill beside the Arabic, because when a cashier reads it out
   over the phone the person on the other end needs the word, not the sentence. */
.reason-pill {
  font-family: var(--num); font-size: 11.5px; padding: 1px 7px;
  border-radius: var(--r-pill); background: rgba(0,0,0,.06); color: var(--muted);
  margin-inline-start: 8px; direction: ltr; unicode-bidi: isolate;
}

/* ══════════════════════════════════════════════════════════════ register */

.reg { display: grid; grid-template-columns: 1fr 380px; height: 100%; min-height: 0; }
.reg-left { display: grid; grid-template-rows: auto auto 1fr; min-height: 0; min-width: 0; }

.reg-search { padding: 12px 14px; background: var(--surface); border-bottom: 1px solid var(--line);
              display: flex; gap: 10px; align-items: center; }
.reg-search input { font-size: 16px; }

.reg-sections { display: flex; gap: 6px; padding: 10px 14px; overflow-x: auto;
                background: var(--surface); border-bottom: 1px solid var(--line); }
.reg-sections button { white-space: nowrap; min-height: 38px; padding: 4px 14px;
                       border-radius: var(--r-pill); background: var(--surface-2); font-size: 14px; }
.reg-sections button[aria-pressed="true"] { background: var(--accent); color: #fff; font-weight: 600; }

.reg-grid { padding: 14px; overflow-y: auto; display: grid; align-content: start;
            grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 10px; }

.prod {
  display: flex; flex-direction: column; justify-content: space-between; gap: 6px;
  min-height: 92px; padding: 12px; text-align: start;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
  box-shadow: var(--shadow); color: var(--ink);
}
.prod:hover:not(:disabled) { border-color: var(--accent); }
.prod .pname { font-weight: 600; font-size: 14.5px; line-height: 1.3; }
.prod .pprice { font-family: var(--num); font-variant-numeric: tabular-nums;
                direction: ltr; unicode-bidi: isolate; color: var(--accent-press); font-weight: 600; }
.prod .pflags { display: flex; gap: 4px; flex-wrap: wrap; }
.prod .tag { font-size: 11px; padding: 1px 7px; border-radius: var(--r-pill);
             background: var(--surface-2); color: var(--muted); }
.prod .tag.offer { background: var(--ok-weak); color: var(--ok); }
.prod:disabled { opacity: .48; }
.prod.out { border-style: dashed; }

/* THE TICKET. Its own scroll region with the totals pinned under it, so a
   twenty-line order never pushes the payable off the screen. */
.ticket { display: grid; grid-template-rows: auto 1fr auto; background: var(--surface);
          border-inline-start: 1px solid var(--line); min-height: 0; }
.ticket-head { padding: 12px 14px; border-bottom: 1px solid var(--line);
               display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ticket-lines { overflow-y: auto; padding: 6px 0; }
.tline { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px;
         padding: 10px 14px; border-bottom: 1px solid var(--line); cursor: pointer; }
.tline:hover { background: var(--surface-2); }
.tline[aria-selected="true"] { background: var(--accent-weak); }
.tline .tname { font-weight: 600; font-size: 14.5px; }
.tline .tmeta { grid-column: 1; color: var(--muted); font-size: 12.5px; }
.tline .tamt { grid-row: 1 / span 2; align-self: center; font-family: var(--num);
               font-variant-numeric: tabular-nums; direction: ltr; unicode-bidi: isolate;
               font-weight: 600; }
.tline.void { opacity: .5; text-decoration: line-through; }

.ticket-foot { border-top: 1px solid var(--line); padding: 12px 14px; background: var(--surface-2); }
.ticket-total { display: flex; justify-content: space-between; font-size: 14px; padding: 3px 0;
                color: var(--muted); }
.ticket-total.big { font-size: 21px; color: var(--ink); font-weight: 700; padding-top: 8px;
                    border-top: 1px dashed var(--line-strong); margin-top: 6px; }
.ticket-actions { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 10px; }
.ticket-actions button { min-height: 44px; padding: 4px 6px; font-size: 13.5px; }
.pay-btn { width: 100%; min-height: 60px; font-size: 20px; margin-top: 10px; font-weight: 700; }

/* keypad — used by the pay sheet and the quantity editor alike */
.keypad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.keypad button { min-height: 56px; font-size: 21px; font-family: var(--num); font-weight: 600; }
.keypad button.wide { grid-column: span 2; }

/* ══════════════════════════════════════════════════════════════ dialogs */

.sheet-back {
  position: fixed; inset: 0; background: rgba(30, 23, 41, .45);
  display: grid; place-items: center; padding: 20px; z-index: 60;
}
.sheet {
  background: var(--surface); border-radius: 18px; box-shadow: var(--shadow-lift);
  width: min(560px, 100%); max-height: 90dvh; display: grid;
  grid-template-rows: auto 1fr auto; overflow: hidden;
}
.sheet.wide { width: min(900px, 100%); }
.sheet-head { padding: 16px 18px 10px; border-bottom: 1px solid var(--line);
              display: flex; align-items: center; gap: 10px; }
.sheet-head h3 { margin: 0; font-size: 18px; font-weight: 600; }
.sheet-body { padding: 16px 18px; overflow-y: auto; }
.sheet-foot { padding: 12px 18px 16px; border-top: 1px solid var(--line);
              display: flex; gap: 10px; justify-content: flex-end; }

/* ══════════════════════════════════════════════════════════ permissions */

.perm-group { border: 1px solid var(--line); border-radius: var(--r-card); padding: 12px; margin-bottom: 12px; }
.perm-group h4 { margin: 0 0 8px; font-size: 14px; color: var(--muted); font-weight: 600; }
.perm-row { display: flex; gap: 10px; align-items: flex-start; padding: 8px 4px; border-radius: 8px; }
.perm-row:hover { background: var(--surface-2); }
.perm-row input { margin-top: 3px; flex: none; }
.perm-row .pdesc { color: var(--muted); font-size: 12.5px; }
.perm-row.locked { opacity: .5; }
.preset-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }

/* ══════════════════════════════════════════════════════════════ kitchen */

.kds { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; }
.kot { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
       box-shadow: var(--shadow); overflow: hidden; }
.kot header { padding: 10px 12px; background: var(--accent-weak); color: var(--accent-press);
              display: flex; justify-content: space-between; align-items: center; font-weight: 600; }
.kot.late header { background: var(--bad-weak); color: var(--bad); }
.kot ul { list-style: none; margin: 0; padding: 10px 12px; }
.kot li { padding: 5px 0; border-bottom: 1px solid var(--line); font-size: 15px; }
.kot li:last-child { border: 0; }
.kot footer { padding: 10px 12px; }

/* ══════════════════════════════════════════════════════════════ toasts */

#posToasts { position: fixed; inset-block-end: 18px; inset-inline-start: 50%;
             transform: translateX(50%); z-index: 90; display: grid; gap: 8px; }
html[dir="ltr"] #posToasts { transform: translateX(-50%); }
.toast { background: var(--ink); color: #fff; padding: 12px 18px; border-radius: var(--r-pill);
         box-shadow: var(--shadow-lift); font-size: 14.5px; max-width: 90vw; }
.toast.bad { background: var(--bad); }
.toast.ok  { background: var(--ok); }

/* ══════════════════════════════════════════════════════════ responsive */

@media (max-width: 1180px) { .reg { grid-template-columns: 1fr 330px; } }

@media (max-width: 900px) {
  :root { --rail: 64px; }
  .pos-rail button > span.label { display: none; }
  .pos-rail .rail-group { display: none; }
  /* Icon-only: the indicator bar is the only thing left saying which section
     is current, so it stays and the padding gives it room. */
  .pos-rail button { justify-content: center; padding: 8px 6px; }
  /* THE TICKET STOPS BEING A COLUMN AND BECOMES THE BOTTOM HALF. A 330px
     ticket beside a 340px product grid is two unusable panes, and the rule
     that matters — the total never leaves the screen — is kept either way. */
  .reg { grid-template-columns: 1fr; grid-template-rows: 1fr minmax(200px, 45%); }
  .ticket { border-inline-start: 0; border-top: 1px solid var(--line-strong); }
  .ticket-actions { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 560px) {
  .pos-top h1 { display: none; }
  .pos-main { padding: 10px; }
  .card { padding: 12px; }
}

/* PRINTING. The page itself is never what goes on paper — a receipt is a PDF
   the server rendered — so if somebody hits Ctrl+P on the till, say so rather
   than spooling a screenshot of the register. */
@media print {
  body::after {
    content: "اطبع الفاتورة من زر «طباعة» في الشاشة — هذه الصفحة ليست الإيصال.";
    display: block; padding: 40px; font-size: 18px; text-align: center;
  }
  #posShell, #posLogin, .sheet-back { display: none !important; }
}
