/* Arabic-first, RTL-first. Every directional rule uses logical properties
   (inline-start/end, not left/right) so one stylesheet serves both directions
   without a mirrored copy to keep in sync.

   ── The look, and why ────────────────────────────────────────────────────
   This is not a dashboard. It is a LEDGER: every screen sets a figure of ours
   beside a figure of Trendyol's and names the difference. So the design is
   built around the two things a ledger needs and a dashboard does not.

   1. The number is the content. Figures are set in tabular numerals at every
      size, so a column lines up digit over digit and a changed value moves
      nothing sideways. Money keeps its own LTR run inside an Arabic page - a
      minus sign that migrates to the far end of a number is not a cosmetic
      problem, it is a different number.

   2. Rules carry meaning. The settlement chain reads
      sales - commission - freight = transfer - VAT - goods = profit,
      and the table draws a hairline where the chain changes hands rather than
      a stripe on every other row. Structure that encodes the content beats
      structure that decorates it.

   Colour: petrol ink for the chrome, paper for the workspace, brass for the
   one thing that is interactive. Green and oxide red are spent ONLY on the
   direction money moved - never on navigation, never on state - so a red
   figure means the same thing on every screen in the product. */

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

:root {
  /* Petrol ink rather than a tinted grey. The chrome is a colour, so the white
     sheets in front of it read as paper instead of as more interface. */
  --ink:        #0f1b24;
  --ink-2:      #46545f;
  --muted:      #75828c;
  --bg:         #eceff1;
  --panel:      #ffffff;
  --panel-2:    #f4f7f8;
  --line:       #e0e5e8;
  --line-2:     #c6cfd5;
  /* Brass: a ledger's ruled gold, and deliberately not the default SaaS blue.
     Two values because one cannot do both jobs - the deep one passes contrast
     as text on white, the lit one is for fills and indicators where the text
     sits on top of it. */
  --accent:     #8a5f22;
  --accent-lit: #b4823c;
  --accent-ink: #ffffff;
  --accent-bg:  #f9f2e4;
  /* Money direction. Not used for anything else, anywhere. */
  --good:       #16694a;
  --good-bg:    #e5f2ec;
  --bad:        #9e2620;
  --bad-bg:     #fbecea;
  --warn:       #7d5507;
  --warn-bg:    #fbf1db;
  --info-bg:    #eef2f4;
  /* One elevation, spent only on things that genuinely float. A shadow under
     every card is the SaaS-kit tell, and it flattens hierarchy by giving the
     unimportant exactly the same lift as the important. */
  --shadow:     none;
  --shadow-lg:  0 14px 34px -10px rgba(15,27,36,.30);
  --radius:     8px;
  --radius-sm:  6px;
  --nav-w:      244px;
  --font: "IBM Plex Sans Arabic", "IBM Plex Sans", "Segoe UI", system-ui,
          -apple-system, "Noto Sans Arabic", "Dubai", Tahoma, Arial, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink:#e6ecf0; --ink-2:#aebac3; --muted:#7f8d97;
    --bg:#091117; --panel:#111d25; --panel-2:#17242d;
    --line:#22323c; --line-2:#33454f;
    --accent:#d9a75c; --accent-lit:#d9a75c; --accent-ink:#12202a; --accent-bg:#241d10;
    --good:#4fbf8d; --good-bg:#0e2a20; --bad:#f08a80; --bad-bg:#2b1513;
    --warn:#dfae4c; --warn-bg:#2a2110; --info-bg:#17242d;
    --shadow:none; --shadow-lg:0 14px 34px -10px rgba(0,0,0,.65);
  }
}
:root[data-theme="dark"] {
  --ink:#e6ecf0; --ink-2:#aebac3; --muted:#7f8d97;
  --bg:#091117; --panel:#111d25; --panel-2:#17242d;
  --line:#22323c; --line-2:#33454f;
  --accent:#d9a75c; --accent-lit:#d9a75c; --accent-ink:#12202a; --accent-bg:#241d10;
  --good:#4fbf8d; --good-bg:#0e2a20; --bad:#f08a80; --bad-bg:#2b1513;
  --warn:#dfae4c; --warn-bg:#2a2110; --info-bg:#17242d;
  --shadow:none; --shadow-lg:0 14px 34px -10px rgba(0,0,0,.65);
}

html, body { margin:0; padding:0; }
body {
  background: var(--bg); color: var(--ink); font-family: var(--font);
  font-size: 15px; line-height: 1.55; -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Every figure in the product, at every size. Set once here so no component
     has to remember, and so a column of money never shifts under its header. */
  font-variant-numeric: tabular-nums;
}
[dir="rtl"] body { font-size: 15.5px; line-height: 1.72; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }
h1,h2,h3,h4 { margin: 0; font-weight: 600; letter-spacing: -.011em; }
[dir="rtl"] h1, [dir="rtl"] h2, [dir="rtl"] h3 { letter-spacing: 0; font-weight: 650; }

/* Keyboard focus, once, everywhere. Brass because brass is what interactive
   means here, and offset so it never sits on top of the thing it marks. */
:focus-visible {
  outline: 2px solid var(--accent-lit); outline-offset: 2px; border-radius: 3px;
}

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

/* ------------------------------------------------------------- layout -- */
.shell { display: flex; min-height: 100vh; }

/* The spine. Dark, so the workspace beside it reads as a sheet of paper
   rather than as another panel - one change that does more for the product
   than any amount of card polish. */
.side {
  inline-size: var(--nav-w); flex: 0 0 var(--nav-w);
  background: var(--ink); color: #cfd9df;
  border-inline-end: 1px solid rgba(255,255,255,.06);
  display: flex; flex-direction: column; position: sticky; inset-block-start: 0;
  block-size: 100vh; overflow-y: auto;
}
.side a { color: inherit; }
.brand { padding: 20px 18px 16px; border-block-end: 1px solid rgba(255,255,255,.08); }
.brand .logo {
  display:flex; align-items:center; gap:10px; font-weight:650; font-size:15px;
  color:#fff; letter-spacing: -.01em;
}
.brand .dot {
  inline-size:28px; block-size:28px; border-radius:7px;
  background: var(--accent-lit); color:#1a1005;
  display:grid; place-items:center; font-size:13.5px; font-weight:700; flex:0 0 28px;
}
.brand .sub { font-size:11.5px; color: rgba(255,255,255,.46); margin-block-start:6px; }

.nav { padding: 12px 10px; flex: 1; }
.nav a {
  display:flex; align-items:center; gap:11px; padding: 8px 11px;
  border-radius: var(--radius-sm); color: rgba(255,255,255,.72);
  font-size: 14px; margin-block-end: 1px; text-decoration:none;
  transition: background .12s ease, color .12s ease;
}
.nav a:hover { background: rgba(255,255,255,.07); color:#fff; text-decoration:none; }
/* The current page is marked by a brass rule on the leading edge, not by a
   filled pill: a filled row competes with the money colours two columns away. */
.nav a.on {
  background: rgba(255,255,255,.09); color:#fff; font-weight: 600;
  box-shadow: inset 3px 0 0 0 var(--accent-lit);
}
[dir="rtl"] .nav a.on { box-shadow: inset -3px 0 0 0 var(--accent-lit); }
.nav a .ic { inline-size:17px; text-align:center; flex:0 0 17px; opacity:.7; }
.nav a.on .ic { opacity: 1; color: var(--accent-lit); }
.nav .sep {
  margin: 16px 11px 6px; font-size: 11px; letter-spacing: .07em;
  text-transform: uppercase; color: rgba(255,255,255,.38); font-weight: 600;
}
[dir="rtl"] .nav .sep { text-transform: none; letter-spacing: 0; font-size: 12px; }
.nav a .badge {
  margin-inline-start: auto; background: var(--bad); color:#fff; font-size:11px;
  min-inline-size: 19px; text-align:center; border-radius: 9px; padding: 1px 6px;
  font-weight: 600;
}
.side-foot {
  padding: 13px; border-block-start: 1px solid rgba(255,255,255,.08);
  font-size: 12.5px; color: rgba(255,255,255,.6);
}
.side-foot .who { color:#fff; font-weight: 600; }
.side-foot .role { color: rgba(255,255,255,.45); font-size: 11.5px; }
.side-foot .row { display:flex; gap:6px; margin-block-start:10px; }
.side-foot .btn {
  background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.14);
  color: rgba(255,255,255,.85);
}
.side-foot .btn:hover { background: rgba(255,255,255,.15); color:#fff; }

.main { flex: 1; min-inline-size: 0; display: flex; flex-direction: column; }
.topbar {
  display:flex; align-items:center; gap:14px; padding: 15px 28px;
  background: color-mix(in srgb, var(--panel) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(8px);
  border-block-end: 1px solid var(--line);
  position: sticky; inset-block-start: 0; z-index: 20;
}
.topbar h1 { font-size: 19px; }
.topbar .spacer { flex: 1; }
.content { padding: 24px 28px 72px; max-inline-size: 1500px; width: 100%; }

/* -------------------------------------------------------------- bits -- */
.card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.card.p { padding: 18px 20px; }
.grid { display: grid; gap: 12px; }
.g2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.g3 { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.g4 { grid-template-columns: repeat(auto-fill, minmax(185px, 1fr)); }
/* Five to a row, fixed rather than fitted. `auto-fill` lets the count change
   with the window, and two blocks of figures that are meant to be read down
   the page do not line up if one of them wraps a card earlier than the other. */
.g5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
@media (max-width: 1360px) { .g5 { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (max-width: 820px)  { .g5 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.row.end { justify-content: flex-end; }
.stack { display:flex; flex-direction:column; gap:12px; }
.mt { margin-block-start: 24px; }
.mb { margin-block-end: 14px; }

/* A section heading is a rule with a name on it, so the eye finds the break
   before it reads the words. */
.sect {
  display: flex; align-items: center; gap: 12px;
  font-size: 12px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--muted); font-weight: 650; margin: 30px 0 12px;
}
.sect::after {
  content: ""; flex: 1; block-size: 1px; background: var(--line);
}
[dir="rtl"] .sect { text-transform: none; letter-spacing: 0; font-size: 13.5px; }
.sect:first-child { margin-block-start: 0; }

/* ------------------------------------------------------- figure cards -- */
.kpi { padding: 15px 17px 16px; }
.kpi .k {
  font-size: 12px; color: var(--muted); font-weight: 600; letter-spacing: .01em;
}
.kpi .v {
  font-size: 27px; font-weight: 600; margin-block-start: 7px;
  letter-spacing: -.025em; line-height: 1.12; word-break: keep-all;
  font-feature-settings: "ss01";
  /* Figures stay LTR inside an RTL page. A minus sign that migrates to the far
     side of the number is not a cosmetic problem - it is a different number. */
  direction: ltr; unicode-bidi: isolate;
}
[dir="rtl"] .kpi .v, [dir="rtl"] .kpi .k, [dir="rtl"] .kpi .n { text-align: start; }
[dir="rtl"] .kpi .v { direction: ltr; unicode-bidi: isolate; text-align: right; }
.kpi .n { font-size: 12px; color: var(--muted); margin-block-start: 6px; }
.kpi .v.good { color: var(--good); } .kpi .v.bad { color: var(--bad); }
.kpi .v.warn { color: var(--warn); }
/* The lead row. A hairline of the figure's own colour along the top edge, so
   a screen of cards can be read for direction before it is read for value. */
.kpi.hero { position: relative; padding-block-start: 17px; }
.kpi.hero .v { font-size: 33px; }
.kpi.hero::before {
  content: ""; position: absolute; inset-block-start: -1px; inset-inline: -1px;
  block-size: 2px; border-radius: var(--radius) var(--radius) 0 0;
  background: var(--line-2);
}
.kpi.hero:has(.v.good)::before { background: var(--good); }
.kpi.hero:has(.v.bad)::before  { background: var(--bad); }
.kpi.hero:has(.v.warn)::before { background: var(--warn); }
.kpi[title] { cursor: help; }

/* A card that opens the rows behind its own number. The affordance is the
   whole surface - a lift and a brass edge on hover - rather than a coloured
   figure, because on this product a coloured figure already means something
   else. */
a.kpi.linked { display: block; text-decoration: none; color: inherit;
  transition: border-color .12s ease, transform .12s ease; }
a.kpi.linked:hover { border-color: var(--accent-lit); text-decoration: none;
  transform: translateY(-1px); }
a.kpi.linked:hover .go { opacity: 1; transform: none; }
.kpi .k { display: flex; align-items: center; gap: 5px; }
.kpi .go { color: var(--accent-lit); font-size: 15px; line-height: 1;
  opacity: .45; transition: opacity .12s ease, transform .12s ease;
  transform: translateX(-2px); }
[dir="rtl"] .kpi .go { transform: scaleX(-1) translateX(-2px); }
[dir="rtl"] a.kpi.linked:hover .go { transform: scaleX(-1); }

.badge2 {
  display:inline-flex; align-items:center; gap:5px; font-size: 11.5px; font-weight: 600;
  padding: 2px 8px; border-radius: 5px; border: 1px solid var(--line-2);
  color: var(--ink-2); background: var(--panel-2); white-space: nowrap;
}
.badge2.good { color: var(--good); background: var(--good-bg); border-color: transparent; }
.badge2.bad  { color: var(--bad);  background: var(--bad-bg);  border-color: transparent; }
.badge2.warn { color: var(--warn); background: var(--warn-bg); border-color: transparent; }
.badge2.info { color: var(--accent); background: var(--accent-bg); border-color: transparent; }

/* ------------------------------------------------------------ tables -- */
.tw {
  overflow-x: auto; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--panel);
}
.card .tw { border: 0; border-radius: 0; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
thead th {
  text-align: start; font-size: 11.5px; font-weight: 650; color: var(--ink-2);
  text-transform: uppercase; letter-spacing: .045em; padding: 11px 12px;
  border-block-end: 1px solid var(--line-2); white-space: nowrap;
  background: var(--panel-2); position: sticky; inset-block-start: 0; z-index: 1;
}
[dir="rtl"] thead th { text-transform: none; letter-spacing: 0; font-size: 12.5px; }
tbody td {
  padding: 9px 12px; border-block-end: 1px solid var(--line); vertical-align: middle;
}
tbody tr:last-child td { border-block-end: 0; }
tbody tr:hover td { background: var(--panel-2); }
tfoot th, tfoot td {
  padding: 11px 12px; font-weight: 650; background: var(--panel-2);
  border-block-start: 2px solid var(--line-2); white-space: nowrap;
}
td.num, th.num {
  text-align: end; white-space: nowrap; direction: ltr;
  font-feature-settings: "ss01";
}
[dir="rtl"] td.num, [dir="rtl"] th.num { text-align: start; }
td.mono, .mono {
  font-family: var(--mono); font-size: 12.5px; direction: ltr; text-align: start;
  letter-spacing: -.01em;
}
/* A whole row tinted is a shout, and on the products table most rows carry one
   - a screen of them stops meaning anything and drowns the money colours in
   the cells. Mixed most of the way back to paper: enough to group the rows at a
   glance, not enough to compete with a red figure inside one. */
tr.bad td  { background: color-mix(in srgb, var(--bad-bg)  55%, var(--panel)) !important; }
tr.good td { background: color-mix(in srgb, var(--good-bg) 45%, var(--panel)) !important; }
tr.warn td { background: color-mix(in srgb, var(--warn-bg) 55%, var(--panel)) !important; }
tr.bad:hover td, tr.good:hover td, tr.warn:hover td { filter: brightness(.985); }

/* A link inside a table is a name, not a destination worth colouring. Twenty
   brass rows down the product column put the accent beside every figure and
   left the eye nothing to lock onto; ink with a quiet rule says "clickable"
   without joining the conversation the numbers are having. */
table a { color: var(--ink); text-decoration: underline;
  text-decoration-style: dotted; text-decoration-color: var(--line-2);
  text-underline-offset: 3px; }
table a:hover { text-decoration-style: solid; text-decoration-color: var(--accent-lit);
  color: var(--accent); }
.pos { color: var(--good); font-weight: 600; }
.neg { color: var(--bad); font-weight: 600; }
/* Secondary figures in a money row: VAT, and the ~ that marks an estimated
   freight charge. Present, readable, and visibly not the headline number. */
.dim { color: var(--muted); }
td.dim { font-weight: 400; }
/* A date is two facts - the day, and what the row was doing that day - and the
   pair was breaking across lines mid-number. The cell never wraps; the second
   fact is already a block in the markup, so nothing here needs to make it one.
   (It did once, and that rule put the `~` estimate marker on its own line
   under every freight figure in the table.) */
.tw td:nth-child(2) { white-space: nowrap; }
/* Product names are whatever language the seller typed, inside a page whose
   direction is Arabic. An LTR string in an RTL box overflows at the visual
   left, so the ellipsis lands on the FIRST characters: "Professional 6-in-1
   Hair Styler" was rendering as "...rofessional 6-in-1 Hair Styler".
   `unicode-bidi: plaintext` takes each name's direction from its own first
   strong character - exactly what dir="auto" does - so English truncates at its
   end and Arabic at its end, on the same page. */
/* The days line under a stage date. Quiet, because the date is the fact and
   this is how long getting to it took; green only where the number earns
   something - zero days to dispatch is the cheap freight ladder. */
.stage { font-size: 11px; color: var(--muted); margin-block-start: 1px;
  direction: ltr; unicode-bidi: isolate; text-align: start; }
[dir="rtl"] .stage { text-align: right; }
.stage.ok { color: var(--good); font-weight: 600; }

.tname { max-inline-size: 340px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; unicode-bidi: plaintext; text-align: start; }

/* The same text where it is the heading of a card rather than a table cell:
   there is room for it, so it wraps instead of being cut at all. */
.pname { font-weight: 650; unicode-bidi: plaintext; text-align: start;
  overflow-wrap: anywhere; line-height: 1.35; }

/* A credit note under the sale it reverses. A brass rule on the leading edge
   rather than a fill: the row is a continuation of the one above it, and a
   tinted band reads as a status the way `tr.warn` does. */
tr.credit td { background: var(--accent-bg); }
tr.credit td:first-child { box-shadow: inset 3px 0 0 0 var(--accent-lit); }
[dir="rtl"] tr.credit td:first-child { box-shadow: inset -3px 0 0 0 var(--accent-lit); }
tr.credit:hover td { background: color-mix(in srgb, var(--accent-bg) 70%, var(--panel-2)); }

/* ------------------------------------------------------------- forms -- */
label { display: block; font-size: 12.5px; font-weight: 600; color: var(--ink-2);
  margin-block-end: 5px; }
label .hint { display:block; font-weight: 400; color: var(--muted); font-size: 11.5px;
  margin-block-start: 3px; }
input[type=text], input[type=email], input[type=password], input[type=number],
input[type=search], input[type=date], select, textarea {
  width: 100%; padding: 9px 11px; font-size: 14px; font-family: inherit;
  color: var(--ink); background: var(--panel); border: 1px solid var(--line-2);
  border-radius: var(--radius-sm); outline: none;
  transition: border-color .12s ease, box-shadow .12s ease;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--accent-lit);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-lit) 22%, transparent);
}
input[readonly] { background: var(--panel-2); color: var(--muted); }
textarea { min-block-size: 84px; resize: vertical; }
.field { margin-block-end: 15px; }
.inline-fields { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(210px,1fr)); }
input[type=checkbox] { inline-size: 16px; block-size: 16px; accent-color: var(--accent-lit);
  vertical-align: -2px; }
.check { display: flex; align-items: flex-start; gap: 9px; }
.check label { margin: 0; }

/* A file input renders as the browser's own grey "Choose File" button, in
   English, on an Arabic page - the one control on the product that does not
   belong to it. The native chrome is hidden and the field is dressed as a
   field, leaving the file name where the browser puts it. */
input[type=file] {
  width: 100%; font-family: inherit; font-size: 13px; color: var(--ink-2);
  padding: 7px 9px; background: var(--panel-2);
  border: 1px dashed var(--line-2); border-radius: var(--radius-sm);
}
input[type=file]::file-selector-button {
  font-family: inherit; font-size: 13px; font-weight: 600;
  padding: 6px 13px; margin-inline-end: 11px;
  color: var(--ink); background: var(--panel);
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); cursor: pointer;
}
input[type=file]::file-selector-button:hover { background: var(--panel-2); }

.btn {
  display: inline-flex; align-items: center; justify-content:center; gap: 7px;
  padding: 9px 15px; font-size: 13.5px; font-weight: 600; font-family: inherit;
  border-radius: var(--radius-sm); border: 1px solid var(--line-2);
  background: var(--panel); color: var(--ink); cursor: pointer; white-space: nowrap;
  transition: background .12s ease, border-color .12s ease;
}
.btn:hover { background: var(--panel-2); border-color: var(--muted); text-decoration: none; }
/* The primary action is ink, not brass. Brass marks what is interactive;
   filling a button with it would put the accent on every screen twice. */
.btn.primary { background: var(--ink); border-color: var(--ink); color: #fff; }
.btn.primary:hover { background: #1b2c38; border-color: #1b2c38; }
:root[data-theme="dark"] .btn.primary,
.btn.primary { color: #fff; }
.btn.danger { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 40%, var(--line-2)); }
.btn.danger:hover { background: var(--bad-bg); border-color: var(--bad); }
.btn.ok { color: var(--good); border-color: color-mix(in srgb, var(--good) 40%, var(--line-2)); }
.btn.ok:hover { background: var(--good-bg); border-color: var(--good); }
.btn.sm { padding: 5px 10px; font-size: 12.5px; }
/* A destructive sibling of a safe button: same size, visibly quieter, so
   "replace what is already there" never reads as the obvious next click. */
.btn.ghost { background: transparent; border-style: dashed; color: var(--muted); }
.btn.ghost:hover { color: var(--ink); border-style: solid; }
.btn.wide { width: 100%; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* ------------------------------------------------------------ notices -- */
.note {
  padding: 11px 14px 11px 13px; border-radius: var(--radius-sm); font-size: 13.5px;
  border: 1px solid transparent; margin-block-end: 14px;
  border-inline-start: 3px solid currentColor;
}
/* ---- a warning that folds ------------------------------------------
   Three duplicate pairs fit on screen. Forty would push the table off the top
   of the page, and a warning that buries the thing it is warning about is a
   worse warning. So it collapses - open while the list is short enough to read
   at a glance, shut when it is not. */
details.fold > summary {
  cursor: pointer; list-style: none; display: flex; align-items: center; gap: 8px;
}
details.fold > summary::-webkit-details-marker { display: none; }
details.fold > summary::after {
  content: "▾"; font-size: 11px; opacity: .65; margin-inline-start: auto;
  transition: transform .12s ease;
}
details.fold[open] > summary::after { transform: rotate(180deg); }
.foldbody { margin-block-start: 10px; }

/* One listing per line, and each line its own bidi island.
   A barcode is Latin text on an Arabic page. Inline, the bidi algorithm
   reorders the badge and the code against each other and it stops being clear
   which badge belongs to which barcode - which is not cosmetic when the badge
   is what tells you which half of a duplicate pair to delete. */
.listing {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 3px 0;
}
.listing .bc {
  direction: ltr; unicode-bidi: isolate; font-weight: 600;
  min-inline-size: 108px;
}
.listing .nm { unicode-bidi: isolate; }
.listing .drop { font-size: 11.5px; opacity: .8; }
/* The pairs are separated by a rule rather than a gap: two listings that
   belong together have to look like a pair, not like four loose rows. */
.pair { padding-block: 6px; }
.pair + .pair { border-block-start: 1px solid color-mix(in srgb, currentColor 18%, transparent); }

.note.info { background: var(--info-bg); color: var(--ink-2); }
.note.good { background: var(--good-bg); color: var(--good); }
.note.bad  { background: var(--bad-bg);  color: var(--bad); }
.note.warn { background: var(--warn-bg); color: var(--warn); }
.note.plain { background: var(--panel-2); color: var(--ink-2); border-color: var(--line);
  border-inline-start-color: var(--line-2); }
.note strong { font-weight: 700; }
/* A warning built from an English sentence, inside an Arabic page: without
   isolation the trailing full stop jumps to the head of the line. */
.note { unicode-bidi: plaintext; text-align: start; }

.flash-wrap { position: fixed; inset-block-start: 14px; inset-inline-end: 14px; z-index: 100;
  display:flex; flex-direction: column; gap: 8px; max-inline-size: 420px; }
.flash { box-shadow: var(--shadow-lg); animation: slidein .18s ease-out; margin: 0; }
@keyframes slidein { from { opacity:0; transform: translateY(-6px); } to { opacity:1; } }

/* An empty screen is an invitation, not a shrug. */
.empty { padding: 40px 20px; text-align: center; color: var(--muted); font-size: 14px; }

/* -------------------------------------------------------------- tabs -- */
.tabs { display: flex; gap: 2px; border-block-end: 1px solid var(--line);
  margin-block-end: 18px; overflow-x: auto; }
.tabs a {
  padding: 9px 14px; font-size: 13.5px; font-weight: 600; color: var(--muted);
  border-block-end: 2px solid transparent; white-space: nowrap; text-decoration: none;
  margin-block-end: -1px;
}
.tabs a:hover { color: var(--ink); text-decoration: none; }
.tabs a.on { color: var(--ink); border-block-end-color: var(--accent-lit); }

/* ------------------------------------------------------------ charts -- */
.bars { display: flex; flex-direction: column; gap: 7px; }
.bar-row { display: grid; grid-template-columns: minmax(120px, 1.6fr) 3fr auto;
  gap: 10px; align-items: center; font-size: 13px; }
.bar-row .lbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--ink-2); unicode-bidi: plaintext; text-align: start; }
.bar-track { display: block; background: var(--panel-2); border-radius: 3px;
  block-size: 9px; overflow: hidden; }
/* display:block is load-bearing - inline elements ignore inline-size and
   block-size, which is why these bars rendered as empty tracks. */
.bar-fill { display: block; block-size: 100%; border-radius: 3px;
  background: var(--good); min-inline-size: 2px; }
.bar-fill.neg { background: var(--bad); }
.bar-row .val { font-weight: 600; min-inline-size: 78px; text-align: end; direction: ltr; }

.donut-wrap { display:flex; align-items:center; gap: 22px; flex-wrap: wrap; }
.legend { display:flex; flex-direction:column; gap: 6px; font-size: 13px; }
.figure { direction: ltr; unicode-bidi: isolate; font-weight: 650; }
.legend i { display:inline-block; inline-size:10px; block-size:10px; border-radius:2px;
  margin-inline-end: 8px; }

/* ------------------------------------------------------------- login -- */
/* The one screen with no data on it, so it is the one screen that can carry
   the chrome colour full-bleed. */
.login-page { min-height: 100vh; display: grid; place-items: center; padding: 24px;
  background: var(--ink);
  background-image:
    radial-gradient(1100px 520px at 50% -12%, rgba(180,130,60,.20), transparent 70%);
}
.login-box { inline-size: 100%; max-inline-size: 400px; }
.login-box .card { padding: 28px 28px 24px; box-shadow: var(--shadow-lg); }
.login-head { text-align: center; margin-block-end: 20px; }
.login-head .dot { inline-size: 44px; block-size: 44px; border-radius: 12px;
  background: var(--accent-lit); color: #1a1005; display: grid; place-items: center;
  font-size: 20px; font-weight: 700; margin: 0 auto 13px; }
.login-head h1 { font-size: 20px; }
.login-head p { color: var(--muted); font-size: 13.5px; margin: 6px 0 0; }
.login-foot { text-align: center; margin-block-start: 16px; font-size: 12.5px;
  color: rgba(255,255,255,.5); }
.login-foot a { color: rgba(255,255,255,.8); }

/* ------------------------------------------------------------ wizard -- */
.steps { display: flex; flex-direction: column; gap: 10px; }
.step {
  display: flex; gap: 14px; align-items: flex-start; padding: 16px 18px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
}
.step.done { border-color: color-mix(in srgb, var(--good) 40%, var(--line)); }
.step .num {
  inline-size: 28px; block-size: 28px; flex: 0 0 28px; border-radius: 50%;
  background: var(--panel-2); color: var(--muted); display: grid; place-items: center;
  font-weight: 700; font-size: 13px; border: 1px solid var(--line-2);
}
.step.done .num { background: var(--good); color: #fff; border-color: transparent; }
.step .body { flex: 1; min-inline-size: 0; }
.step .body h3 { font-size: 15px; }
.step .body p { margin: 4px 0 0; color: var(--muted); font-size: 13px; }
.step .act { flex: 0 0 auto; }

/* ---------------------------------------------------------- progress -- */
.prog { background: var(--panel-2); border-radius: 20px; block-size: 7px; overflow: hidden; }
.prog > i { display:block; block-size:100%; background: var(--accent-lit);
  transition: inline-size .3s ease; }
.joblog {
  font-family: var(--mono); font-size: 12px; direction: ltr;
  text-align: start; background: var(--ink); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 12px 14px; max-block-size: 240px;
  overflow: auto; white-space: pre-wrap; color: #cfd9df; line-height: 1.6;
}

/* ------------------------------------------------------------ modals -- */
.modal-bg {
  position: fixed; inset: 0; background: rgba(9,17,23,.55); z-index: 200;
  display: grid; place-items: center; padding: 20px;
  backdrop-filter: blur(2px);
}
.modal { background: var(--panel); border-radius: var(--radius); box-shadow: var(--shadow-lg);
  inline-size: 100%; max-inline-size: 620px; max-block-size: 90vh; overflow: auto; }
.modal .head { padding: 16px 20px; border-block-end: 1px solid var(--line);
  display: flex; align-items: center; gap: 12px; }
.modal .head h2 { font-size: 16px; flex: 1; }
.modal .body { padding: 20px; }
.modal .foot { padding: 14px 20px; border-block-start: 1px solid var(--line);
  display: flex; gap: 9px; justify-content: flex-end; background: var(--panel-2); }
.x { background: none; border: none; font-size: 20px; color: var(--muted);
  cursor: pointer; line-height: 1; padding: 0 4px; }

/* ----------------------------------------------------------- mobile -- */
.burger { display: none; }
@media (max-width: 900px) {
  .side {
    position: fixed; inset-block: 0; inset-inline-start: 0; z-index: 60;
    transform: translateX(-100%); transition: transform .2s ease;
    box-shadow: var(--shadow-lg);
  }
  [dir="rtl"] .side { transform: translateX(100%); }
  body.nav-open .side { transform: none; }
  body.nav-open::after {
    content:""; position: fixed; inset: 0; background: rgba(9,17,23,.5); z-index: 50;
  }
  .burger { display: inline-flex; }
  .content { padding: 16px 14px 60px; }
  .topbar { padding: 12px 14px; }
  .kpi .v { font-size: 22px; }
  .kpi.hero .v { font-size: 26px; }
  .sect { margin-block-start: 22px; }
}

@media print {
  .side, .topbar, .btn, .tabs, .flash-wrap { display: none !important; }
  .content { padding: 0; max-inline-size: none; }
  .card { box-shadow: none; border-color: #ccc; break-inside: avoid; }
  .kpi.hero::before { display: none; }
  body { background: #fff; font-size: 11pt; }
}

/* A bulk action bar. Quiet until something is ticked - a control that looks
   armed and does nothing is worse than one that is visibly waiting. */
.bulkbar { opacity: .55; transition: opacity .12s ease, border-color .12s ease; }
.bulkbar.armed { opacity: 1; border-color: var(--accent-lit); }

/* ---- coverage strip (pricing) ---------------------------------------
   One square per barcode. Filled means a recorded cost; empty means no
   knowable break-even - a different thing from a thin margin, so it has
   to look different rather than merely worse. */
.strip{display:flex;flex-wrap:wrap;gap:2px;margin-top:4px}
.strip .seg{width:8px;height:17px;border-radius:1px;background:var(--line-2)}
.strip .seg.has{background:var(--good)}
.seg-key{display:inline-block;width:9px;height:9px;border-radius:1px;
         margin-inline-end:6px;background:var(--line-2)}
.seg-key.has{background:var(--good)}

/* ---- editable number cells (pricing) --------------------------------
   Selector note, learned the hard way: the base rule is
   `input[type=number], ...` above. A bare `.cell-edit` is (0,1,0) and loses -
   so width:100% inside a shrink-to-fit table cell won, the box collapsed, and
   9px/11px of padding pushed the digits out of sight. Empty white boxes where
   the numbers should be. Hence the type qualifier.

   The field is quiet but never invisible: a real border, because a number you
   can change should look changeable, and the figure itself always legible. */
input[type=number].cell-edit {
  inline-size: 88px; min-inline-size: 72px; width: 88px;
  padding: 5px 8px; font-size: 13.5px; line-height: 1.3;
  text-align: end;
  color: var(--ink); background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
input[type=number].cell-edit::placeholder { color: var(--muted); font-weight: 400; }
input[type=number].cell-edit:hover { border-color: var(--line-2); }
input[type=number].cell-edit:focus {
  border-color: var(--accent-lit);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-lit) 22%, transparent);
}
/* A SKU carrying its own freight rather than the global one. */
input[type=number].cell-edit.own { font-weight: 700; border-color: var(--accent-lit); }
/* The spinners steal ~14px of an 88px box and nobody nudges a price by arrows. */
input[type=number].cell-edit::-webkit-outer-spin-button,
input[type=number].cell-edit::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
input[type=number].cell-edit { -moz-appearance: textfield; appearance: textfield; }

/* ---- read first, edit on purpose ------------------------------------
   Three columns of open input boxes turned a table into a form, and a price
   is read many more times than it is changed. So the figure sits as plain
   text in the same weight as every other number in the row, and only becomes
   a field when somebody asks for it.

   The affordance is deliberately quiet and appears on ROW hover, not on the
   cell's own: a dotted rule under a number that is otherwise identical to its
   neighbours is enough to say "this one you can change", without three boxes
   shouting it on every row at once. */
.cell { display: inline-flex; align-items: center; gap: 3px; justify-content: flex-end; }
.cell-val {
  appearance: none; -webkit-appearance: none;
  background: transparent; border: 1px solid transparent;
  padding: 5px 8px; margin: 0;
  font: inherit; font-size: 13.5px; line-height: 1.3;
  color: var(--ink); text-align: end; cursor: text;
  border-radius: var(--radius-sm);
  inline-size: 88px; min-inline-size: 72px;
  font-variant-numeric: tabular-nums;
}
tr:hover .cell-val { border-block-end-color: var(--line-2); border-block-end-style: dotted; }
.cell-val:hover { background: var(--panel); border-color: var(--line); }
.cell-val:focus-visible {
  outline: none; border-color: var(--accent-lit);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-lit) 22%, transparent);
}
/* A SKU carrying its own freight rather than the inherited one. */
.cell-val.own { font-weight: 700; }
/* The unit rides ON the number. A commission is the only rate in a row of
   riyals; a bare 10.50 between a cost and a freight charge reads as money,
   which is exactly the mistake that makes somebody type 0.105. */
.cell-val .u { font-style: normal; color: var(--muted); font-size: 11.5px;
               margin-inline-start: 1px; }

/* The tick that appears the moment a figure changes. Enter still saves, but a
   keyboard shortcut cannot be the only way to keep what you typed. */
.cell-ok {
  appearance: none; -webkit-appearance: none; cursor: pointer;
  inline-size: 24px; block-size: 24px; padding: 0; line-height: 1;
  font-size: 13px; font-weight: 700;
  color: #fff; background: var(--good); border: 0;
  border-radius: var(--radius-sm);
}
.cell-ok:hover { filter: brightness(1.08); }

/* The product column. With thirteen columns and every numeric one at a fixed
   width, the one free column absorbs all the slack - which is how the name
   grew to eat the table and pushed the money off the right of the screen.
   Capped here, and wrapped to two lines rather than truncated: a beauty SKU is
   told apart from its sibling by the words at the END of the name (the size,
   the shade), so an ellipsis there hides exactly the part that identifies it. */
.tw td.prod, .tw th.prod { max-inline-size: 300px; }
.tw td.prod .pname {
  max-inline-size: 300px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

.cell-wrap { display: inline-flex; align-items: center; gap: 3px; justify-content: flex-end; }
.cell-wrap .src { font-style: normal; color: var(--muted); font-size: 11px; inline-size: 6px; }

td.acts { white-space: nowrap; text-align: end; }
td.acts .btn { margin-inline-start: 5px; }
td.acts .inline-form { display: inline; }
/* Give the edited columns room so the header and the field line up instead of
   the cell sizing itself from whichever row happens to hold the widest value. */
.tw th.editcol, .tw td.editcol { inline-size: 104px; }

/* A product nothing has ever been ordered of. Deliberately quiet - it is
   context for the blanks beside it, not a warning about the product. */
.badge2.nosale {
  background: transparent; color: var(--muted);
  border: 1px dashed var(--line-2); font-weight: 500;
  margin-inline-start: 6px;
}

/* The x on a removable chip. Its own class rather than a pile of inline
   styles: a button inside a badge needs its inherited chrome stripped, and
   doing that in five attributes on one element is how the next one gets it
   subtly different. */
.chip-x {
  border: 0; background: none; cursor: pointer;
  padding: 0 3px; margin-inline-start: 2px;
  font-size: 14px; line-height: 1; color: inherit; opacity: .55;
}
.chip-x:hover { opacity: 1; color: var(--bad); }
.inline-form { display: inline; }

/* ---- key/value tables (order detail) --------------------------------
   A two-column fact list, not a data grid: no header row, the label muted
   and the value carrying the weight. Borderless on purpose - a page that
   is mostly single facts reads as a form, and ruling every line makes it
   look like data that can be sorted when it cannot. */
table.kv { font-size: 13px; }
table.kv td { padding: 6px 0; border: 0; vertical-align: baseline; }
table.kv td:first-child { inline-size: 40%; padding-inline-end: 10px; color: var(--muted); }
table.kv tr.warn td { background: var(--warn-bg); }
table.kv tr.warn td:first-child { padding-inline-start: 6px; }
