/* ============================================================
   PROTOTYPE — DIGITAL OPERATIONS PRODUCT PAGE
   ------------------------------------------------------------
   Loads AFTER prototype-trade.css (the shared product-page
   vocabulary: .frame, .screen-crop, .msite, .priceband, .ba,
   .aud, .inc, .tier) and AFTER prototype-lead.css (.msite--pro,
   the grown-up Wadi marketing site, which this page's "before"
   panel reuses unchanged).

   What is new here is .app — a drawn WEB APPLICATION rather than
   a drawn marketing site. Digital Operations is the tier where
   the website stops being pages and becomes screens people log
   into, so the centrepiece cannot be another .msite. An .app has
   a nav rail, a signed-in account, a working area, and data in
   it.

   Modules drawn on top of .app:
       .kpi   stat tiles
       .pnl   a panel — the app's unit of content
       .tbl   a data table (orders, line items, stock)
       .pill  a status chip
       .live  the "synced N minutes ago" integration marker
       .tl    an order timeline
       .bars  stock by branch
       .reo   the repeat-order picker
       .sync  the integration screen
       .sheet the spreadsheet in the "before" panel

   Same brand as the Lead Engine page: Wadi Equipment, two years
   further on. Same drawn-not-screenshotted rule, so every screen
   translates and mirrors for free.
   ============================================================ */


/* ============================================================
   0. WADI, ON AN APP SURFACE
   ------------------------------------------------------------
   The --m-* names are re-declared rather than inherited: the
   palette lives on .msite--wadi in prototype-lead.css and an
   .app is not an .msite. .msite__status is reused verbatim on
   the phone renderings, and it reads --m-ink, so the names have
   to match. At port time these two blocks should become one
   brand class that both roots carry.
   ============================================================ */

.app--wadi {
  --m-ink:    #1f2933;
  --m-body:   #59636e;
  --m-line:   #e3e5e4;
  --m-cream:  #f4f5f3;
  --m-deep:   #1b3a4b;   /* steel navy */
  --m-stone:  #c07a22;   /* equipment amber */

  /* App-surface tokens. A signed-in tool is cooler and flatter
     than a marketing page — panels on a tinted canvas, hairlines
     rather than shadows. */
  --a-canvas: #f1f4f6;
  --a-panel:  #ffffff;
  --a-line:   #e2e7ec;
  --a-faint:  #f7f9fa;
  --a-ok:     #1f8a4c;
  --a-warn:   #b26a06;
  --a-bad:    #b3261e;
}


/* ============================================================
   1. THE APPLICATION SHELL
   ============================================================ */

.app {
  inline-size: 100%;
  block-size: 100%;
  overflow: hidden;
  background: var(--a-canvas);
  font-family: var(--font-body);
  color: var(--m-body);
  text-align: start;
  display: grid;
  /* Rail, then everything else. minmax(0,1fr) for the same
     min-content reason .msite carries it: one nowrap run inside
     (an order reference, an email) would otherwise size the
     column wider than the frame and clip the inline END, which
     in Arabic is the readable edge. */
  grid-template-columns: auto minmax(0, 1fr);
  /* Denser than .msite--pro (1.78cqw), which is itself denser
     than .msite (2.15cqw). The three root ems ARE the three
     tiers: same frame, progressively more inside it. */
  font-size: clamp(0.38rem, 1.45cqw, 0.72rem);
  line-height: 1.45;
  /* One row, stated: an implicit auto row does stretch here, but the
     phone rendering re-declares the columns and it is easier to read
     the shell if both axes are written down. */
  grid-template-rows: minmax(0, 1fr);
}
[lang="ar"] .app, .app[dir="rtl"] { font-family: var(--font-arabic); }

/* ---- The rail ---- */
.app__rail {
  background: var(--m-deep);
  color: rgba(255, 255, 255, 0.72);
  padding: 0.95em 0.85em;
  display: grid;
  /* Brand, tag, account, then the nav takes the rest. The account sits at
     the TOP, not the bottom: the hero's phone hangs over the frame's
     bottom inline-start corner (shared geometry, measured on the other two
     product pages) and would cover exactly the chip that says whose portal
     this is. Putting the workspace at the top is a real app pattern, so
     the constraint costs nothing. */
  grid-template-rows: auto auto auto minmax(0, 1fr);
  gap: 0.9em;
  inline-size: 9.5em;
  align-content: start;
}
.app__brand {
  display: flex;
  align-items: center;
  gap: 0.4em;
  color: #fff;
  font-weight: 700;
  font-size: 0.78em;
  letter-spacing: 0.06em;
  min-inline-size: 0;
}
.app__brand svg { inline-size: 1.5em; block-size: 1.5em; flex: none; }
.app__railtag {
  font-size: 0.58em;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--m-stone);
  font-weight: 700;
}
.app__nav { display: grid; gap: 0.12em; align-content: start; }
.app__navitem {
  display: flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.42em 0.55em;
  border-radius: 0.35em;
  font-size: 0.66em;
  white-space: nowrap;
  min-inline-size: 0;
}
.app__navitem svg { inline-size: 1.15em; block-size: 1.15em; flex: none; }
.app__navitem span { overflow: hidden; text-overflow: ellipsis; }
.app__navitem--on {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-weight: 600;
  box-shadow: inset 2px 0 0 var(--m-stone);
}
/* inset-inline-start, drawn with a physical inset above — swap it
   for RTL so the marker stays on the rail's inner edge. */
html[dir="rtl"] .app__navitem--on { box-shadow: inset -2px 0 0 var(--m-stone); }

.app__acct {
  display: flex;
  align-items: center;
  gap: 0.45em;
  padding-block-end: 0.7em;
  border-block-end: 1px solid rgba(255, 255, 255, 0.16);
  min-inline-size: 0;
}
.app__acct i {
  inline-size: 1.7em;
  block-size: 1.7em;
  border-radius: 0.35em;
  background: var(--m-stone);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 0.7em;
  font-weight: 700;
  font-style: normal;
  flex: none;
}
.app__acct div { min-inline-size: 0; }
.app__acct b {
  display: block;
  font-size: 0.62em;
  font-weight: 600;
  color: #fff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app__acct span { display: block; font-size: 0.56em; }

/* Below this the rail is wider than the content it flanks. Real
   apps collapse it to icons; so does the drawing. */
@container screen (max-width: 30rem) {
  .app__rail { inline-size: auto; padding-inline: 0.55em; }
  .app__railtag,
  .app__navitem span,
  .app__acct div { display: none; }
  .app__brand { font-size: 0; gap: 0; }
  .app__brand svg { font-size: 0.78rem; }
  .app__navitem { justify-content: center; padding-inline: 0.35em; }
}

/* ---- Main column ---- */
.app__main { display: grid; grid-template-rows: auto minmax(0, 1fr); min-inline-size: 0; }

.app__top {
  display: flex;
  align-items: center;
  gap: 0.7em;
  padding: 0.7em 0.95em;
  background: var(--a-panel);
  border-block-end: 1px solid var(--a-line);
  min-inline-size: 0;
}
.app__ttl { min-inline-size: 0; }
.app__ttl b {
  display: block;
  font-size: 0.82em;
  font-weight: 700;
  color: var(--m-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app__ttl span { display: block; font-size: 0.6em; }
.app__tools { margin-inline-start: auto; display: flex; align-items: center; gap: 0.45em; flex: none; }
.app__search {
  display: flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.35em 0.7em;
  border-radius: 0.35em;
  background: var(--a-faint);
  box-shadow: inset 0 0 0 1px var(--a-line);
  font-size: 0.62em;
  inline-size: 13.8em;
  white-space: nowrap;
  overflow: hidden;
}
.app__search svg { inline-size: 1.1em; block-size: 1.1em; flex: none; }
.app__lang {
  font-size: 0.62em;
  font-weight: 600;
  color: var(--m-deep);
  padding: 0.3em 0.55em;
  border-radius: 0.3em;
  box-shadow: inset 0 0 0 1px var(--a-line);
}
.app__avatar {
  inline-size: 1.55em;
  block-size: 1.55em;
  border-radius: 50%;
  background: var(--m-deep);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 0.7em;
  font-weight: 700;
}
@container screen (max-width: 26rem) {
  .app__search { display: none; }
}

.app__body {
  padding: 0.85em;
  display: grid;
  gap: 0.7em;
  min-block-size: 0;
  overflow: hidden;
  /* The working area fills the frame. A dashboard that stops two thirds
     of the way down reads as a cropped screenshot rather than a screen,
     and the drawn app is the whole argument of this page. Stat tiles keep
     their content height; whatever follows them takes the rest. */
  grid-template-rows: minmax(0, 1fr);
}
.app__body:has(> .kpi) { grid-template-rows: auto minmax(0, 1fr); }
/* Two-column working areas. The aside is the narrow one. */
.app__split { display: grid; grid-template-columns: 1.6fr 1fr; gap: 0.7em; align-items: stretch; min-block-size: 0; }
@container screen (max-width: 28rem) {
  /* Narrow frames get the primary column only. An aside stacked under
     a table in a 300px-wide drawing is unreadable at any root em. */
  .app__split { grid-template-columns: 1fr; }
  .app__split > :last-child { display: none; }
}
/* Two panels sharing the aside column. */
.app__stack { display: grid; gap: 0.7em; grid-template-rows: auto minmax(0, 1fr); min-block-size: 0; }
/* The other way round: the list stretches, the summary under it does not. */
.app__stack--top { grid-template-rows: minmax(0, 1fr) auto; }
/* Two content-height panels pinned to the ends of a stretched column —
   for asides where neither panel has anything to stretch WITH. */
.app__stack--split { grid-template-rows: auto auto; align-content: space-between; }


/* ============================================================
   2. PANELS, TILES, TABLES
   ============================================================ */

.pnl {
  background: var(--a-panel);
  border: 1px solid var(--a-line);
  border-radius: 0.45em;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  min-block-size: 0;
  overflow: hidden;
}
.pnl__head {
  display: flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.55em 0.7em;
  border-block-end: 1px solid var(--a-line);
  min-inline-size: 0;
}
.pnl__title {
  font-size: 0.68em;
  font-weight: 700;
  color: var(--m-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pnl__act { margin-inline-start: auto; font-size: 0.6em; color: var(--m-deep); font-weight: 600; flex: none; }
.pnl__body { padding: 0.6em 0.7em; display: grid; gap: 0.5em; align-content: start; min-block-size: 0; }
/* A chart panel whose rows should breathe into the height it was given,
   rather than bunching at the top of a stretched box. Tables keep
   align-content:start — spreading table rows apart reads as broken. */
.pnl--fill .pnl__body { align-content: stretch; }
/* A timeline in a stretched panel: the STEPS grow, not the gaps between
   them. The connecting rail is drawn on each step box (inset-block:
   0.95em 0), so spacing the boxes apart with a gap would cut the rail
   into five floating stubs; equal 1fr rows keep it continuous. */
.pnl--fill .tl { align-content: stretch; grid-auto-rows: 1fr; }

/* ---- Stat tiles ---- */
.kpi { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.55em; }
@container screen (max-width: 24rem) { .kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.kpi__tile {
  background: var(--a-panel);
  border: 1px solid var(--a-line);
  border-radius: 0.45em;
  padding: 0.6em 0.7em;
  display: grid;
  gap: 0.1em;
  min-inline-size: 0;
}
.kpi__lbl {
  font-size: 0.58em;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kpi__val {
  font-size: 1.15em;
  font-weight: 700;
  color: var(--m-ink);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kpi__note { font-size: 0.56em; display: flex; align-items: center; gap: 0.25em; }
.kpi__note--up { color: var(--a-ok); }
.kpi__note--warn { color: var(--a-warn); }
.kpi__note svg { inline-size: 0.9em; block-size: 0.9em; }

/* ---- Data table.
   The column template comes in as an inline --tcols, because
   every table on these screens has a different shape and naming
   a modifier per shape would be six classes doing one job. ---- */
.tbl { display: grid; gap: 0; font-size: 0.62em; }
.tbl__row {
  display: grid;
  grid-template-columns: var(--tcols, 1fr);
  gap: 0.5em;
  align-items: center;
  padding: 0.5em 0;
  border-block-end: 1px solid var(--a-line);
  min-inline-size: 0;
}
.tbl__row > * { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tbl__row:last-child { border-block-end: 0; padding-block-end: 0; }
.tbl__row--head {
  padding-block: 0 0.45em;
  font-size: 0.9em;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--m-body);
}
.tbl__row b { color: var(--m-ink); font-weight: 600; }
.tbl__ref { font-variant-numeric: tabular-nums; }
.tbl__num { text-align: end; font-variant-numeric: tabular-nums; }

/* ---- Status chips ---- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  padding: 0.18em 0.5em;
  border-radius: 999px;
  font-size: 0.92em;
  font-weight: 600;
  justify-self: start;
  white-space: nowrap;
}
.pill::before { content: ""; inline-size: 0.4em; block-size: 0.4em; border-radius: 50%; background: currentColor; flex: none; }
.pill--ok   { color: var(--a-ok);   background: color-mix(in srgb, var(--a-ok) 11%, #fff); }
.pill--info { color: var(--m-deep); background: color-mix(in srgb, var(--m-deep) 10%, #fff); }
.pill--warn { color: var(--a-warn); background: color-mix(in srgb, var(--a-warn) 12%, #fff); }
.pill--bad  { color: var(--a-bad);  background: color-mix(in srgb, var(--a-bad) 10%, #fff); }

/* A count left on the shelf reads as a number, not a status: a chip with a
   dot in front of "4" says "state: 4", which is not a thing. */
.qty { font-weight: 700; font-variant-numeric: tabular-nums; text-align: end; }
.qty--bad { color: var(--a-bad); }
.qty--warn { color: var(--a-warn); }

/* ---- The integration marker.
   This is the one element that has to be visible on every screen
   the stock number appears on: it is what makes the number true.
   ---- */
.live {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  font-size: 0.58em;
  font-weight: 600;
  color: var(--a-ok);
  background: color-mix(in srgb, var(--a-ok) 10%, #fff);
  border-radius: 999px;
  padding: 0.25em 0.6em;
  white-space: nowrap;
}
.live::before {
  content: "";
  inline-size: 0.45em;
  block-size: 0.45em;
  border-radius: 50%;
  background: var(--a-ok);
  box-shadow: 0 0 0 0.15em color-mix(in srgb, var(--a-ok) 22%, transparent);
  flex: none;
}
.live--head { margin-inline-start: auto; flex: none; }

.app__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  background: var(--m-deep);
  color: #fff;
  font-size: 0.62em;
  font-weight: 600;
  padding: 0.5em 0.85em;
  border-radius: 0.35em;
  white-space: nowrap;
  justify-self: start;
}
.app__btn svg { inline-size: 1.1em; block-size: 1.1em; }
.app__btn--ghost { background: transparent; color: var(--m-deep); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--m-deep) 30%, transparent); }


/* ============================================================
   3. ORDER TIMELINE
   ------------------------------------------------------------
   The single thing a buyer opens the portal to see. Drawn as a
   rail with the done part filled, so "where is it" is answered
   before any label is read.
   ============================================================ */

.tl { display: grid; gap: 0; }
.tl__step {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.6em;
  padding-block-end: 0.7em;
  position: relative;
}
.tl__step:last-child { padding-block-end: 0; }
/* The connecting rail, drawn on the dot column. */
.tl__step:not(:last-child)::before {
  content: "";
  position: absolute;
  inset-block: 0.95em 0;
  inset-inline-start: 0.42em;
  inline-size: 1px;
  background: var(--a-line);
}
.tl__step--done:not(:last-child)::before { background: color-mix(in srgb, var(--a-ok) 45%, #fff); }
.tl__dot {
  inline-size: 0.85em;
  block-size: 0.85em;
  border-radius: 50%;
  background: #fff;
  box-shadow: inset 0 0 0 1.5px var(--a-line);
  margin-block-start: 0.15em;
  display: grid;
  place-items: center;
  flex: none;
}
.tl__dot svg { inline-size: 0.6em; block-size: 0.6em; color: #fff; }
.tl__step--done .tl__dot { background: var(--a-ok); box-shadow: none; }
.tl__step--on .tl__dot { background: var(--m-stone); box-shadow: 0 0 0 0.18em color-mix(in srgb, var(--m-stone) 20%, transparent); }
.tl__body { min-inline-size: 0; }
.tl__body b { display: block; font-size: 0.64em; font-weight: 600; color: var(--m-ink); }
.tl__body span { display: block; font-size: 0.58em; }
.tl__step--todo .tl__body b { color: var(--m-body); font-weight: 500; }


/* ============================================================
   4. STOCK BY BRANCH
   ------------------------------------------------------------
   Six branches is few enough that bars beat a chart library, and
   an inline-size fill mirrors for free where a canvas would not.
   ============================================================ */

/* space-between, not start: the panel is stretched to the frame and six
   bars bunched at its top read as a chart that failed to load. The bars
   are also deliberately heavy — a 6px rule spread over 300px of panel is
   a hairline chart nobody can read at this scale. */
.bars { display: grid; gap: 0.5em; align-content: space-between; }
.bars__row { display: grid; grid-template-columns: 7.6em minmax(0, 1fr) 3.2em; gap: 0.6em; align-items: center; font-size: 0.62em; }
.bars__lbl { min-inline-size: 0; }
.bars__lbl b { display: block; font-weight: 600; color: var(--m-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bars__lbl span { display: block; font-size: 0.85em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bars__track { block-size: 1.25em; border-radius: 999px; background: var(--a-faint); box-shadow: inset 0 0 0 1px var(--a-line); overflow: hidden; }
.bars__fill { display: block; block-size: 100%; border-radius: 999px; background: var(--m-deep); inline-size: var(--v, 50%); }
.bars__row--low .bars__fill { background: var(--a-warn); }
.bars__val { text-align: end; font-variant-numeric: tabular-nums; color: var(--m-ink); font-weight: 600; }
@container screen (max-width: 22rem) { .bars__row { grid-template-columns: 5.4em minmax(0, 1fr) 2.6em; } }


/* ============================================================
   5. REPEAT ORDERING
   ------------------------------------------------------------
   The reason a portal pays for itself: the buyer's last order,
   with today's stock against it.
   ============================================================ */

.reo { display: grid; gap: 0.45em; align-content: start; }
.reo__item {
  display: grid;
  grid-template-columns: 2.1em minmax(0, 1fr) auto;
  gap: 0.55em;
  align-items: center;
  padding: 0.45em;
  border: 1px solid var(--a-line);
  border-radius: 0.4em;
  min-inline-size: 0;
}
.reo__thumb {
  inline-size: 2.1em;
  block-size: 2.1em;
  border-radius: 0.3em;
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--m-deep) 12%, #fff), color-mix(in srgb, var(--m-stone) 16%, #fff));
  display: grid;
  place-items: center;
  color: var(--m-deep);
  flex: none;
}
.reo__thumb svg { inline-size: 1.1em; block-size: 1.1em; }
.reo__id { min-inline-size: 0; }
.reo__id b { display: block; font-size: 0.64em; font-weight: 600; color: var(--m-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.reo__id span { display: block; font-size: 0.56em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Nested inside .reo__id span, which is already 0.56em — re-declaring
   the size here squared it. <em> is the right element (it IS an
   emphasis on the row) but a stock figure is not italic. */
.reo__stock { font-size: inherit; font-style: normal; font-weight: 600; }
.reo__stock--ok { color: var(--a-ok); }
.reo__stock--low { color: var(--a-warn); }
.reo__qty { display: flex; align-items: center; gap: 0.3em; flex: none; }
.reo__qty i {
  inline-size: 1.25em;
  block-size: 1.25em;
  border-radius: 0.25em;
  box-shadow: inset 0 0 0 1px var(--a-line);
  display: grid;
  place-items: center;
  font-size: 0.7em;
  font-style: normal;
  color: var(--m-deep);
}
.reo__qty b { font-size: 0.66em; font-weight: 700; color: var(--m-ink); min-inline-size: 1.2em; text-align: center; font-variant-numeric: tabular-nums; }
@container screen (max-width: 20rem) { .reo__qty i { display: none; } }


/* ============================================================
   6. THE INTEGRATION SCREEN
   ------------------------------------------------------------
   "Advanced integrations" is the hardest of the three headline
   components to show, because when it works there is nothing to
   see. So it is drawn as what the client actually gets: two
   named systems, the fields that cross between them, and a log
   proving it ran.
   ============================================================ */

.sync { display: grid; gap: 0.7em; grid-template-rows: auto minmax(0, 1fr); min-block-size: 0; }
.sync__wires { display: grid; grid-template-columns: 1fr auto 1fr; gap: 0.5em; align-items: center; }
/* Two source systems feeding one site: they stack in the first column
   rather than each getting their own wire, so the drawing says "these
   both end up in the same place" instead of drawing it twice. */
.sync__srcs { display: grid; gap: 0.5em; min-inline-size: 0; }
@container screen (max-width: 24rem) { .sync__wires { grid-template-columns: 1fr; } .sync__pipe { display: none; } }
.sync__node {
  border: 1px solid var(--a-line);
  border-radius: 0.4em;
  padding: 0.55em 0.65em;
  background: var(--a-faint);
  display: grid;
  gap: 0.15em;
  min-inline-size: 0;
}
.sync__node--site {
  background: color-mix(in srgb, var(--m-deep) 8%, #fff);
  border-color: color-mix(in srgb, var(--m-deep) 45%, #fff);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--m-deep) 8%, transparent);
}
.sync__node b { font-size: 0.64em; font-weight: 700; color: var(--m-ink); display: flex; align-items: center; gap: 0.35em; min-inline-size: 0; }
.sync__node b svg { inline-size: 1.05em; block-size: 1.05em; flex: none; color: var(--m-deep); }
.sync__node span { font-size: 0.56em; }
/* The wire. A dashed rule with an arrowhead, pointing at the
   site — data flows one way, and the drawing should say so. */
.sync__pipe { display: grid; place-items: center; gap: 0.2em; color: var(--m-stone); }
.sync__pipe i {
  display: block;
  inline-size: 2.4em;
  block-size: 0;
  border-block-start: 1.5px dashed currentColor;
}
.sync__pipe svg { inline-size: 0.9em; block-size: 0.9em; }
/* The arrow is drawn pointing at the inline END; in RTL the two
   nodes swap sides, so it has to turn with them. */
html[dir="rtl"] .sync__pipe svg { transform: scaleX(-1); }

.sync__fields { display: flex; flex-wrap: wrap; gap: 0.3em; }
.sync__field {
  font-size: 0.56em;
  padding: 0.22em 0.5em;
  border-radius: 0.28em;
  background: var(--a-faint);
  box-shadow: inset 0 0 0 1px var(--a-line);
  color: var(--m-ink);
  white-space: nowrap;
}
.sync__log { display: grid; gap: 0; font-size: 0.58em; font-variant-numeric: tabular-nums; }
.sync__logrow {
  display: grid;
  grid-template-columns: 4.2em minmax(0, 1fr) auto;
  gap: 0.5em;
  align-items: center;
  padding: 0.35em 0;
  border-block-end: 1px solid var(--a-line);
}
.sync__logrow:last-child { border-block-end: 0; }
.sync__logrow > * { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sync__logrow b { color: var(--m-ink); font-weight: 600; }
.sync__ok { color: var(--a-ok); font-weight: 600; }
@container screen (max-width: 20rem) { .sync__logrow { grid-template-columns: 3.4em minmax(0, 1fr) auto; } }


/* ---- Documents. A portal's quiet win: the paperwork stops being an
   email somebody has to find. ---- */
.doc { display: grid; gap: 0.35em; }
.doc__item {
  display: grid;
  grid-template-columns: 1.5em minmax(0, 1fr) auto;
  gap: 0.5em;
  align-items: center;
  padding: 0.35em 0;
  border-block-end: 1px solid var(--a-line);
  min-inline-size: 0;
}
.doc__item:last-child { border-block-end: 0; padding-block-end: 0; }
.doc__type {
  inline-size: 1.5em;
  block-size: 1.8em;
  border-radius: 0.2em;
  background: color-mix(in srgb, var(--a-bad) 10%, #fff);
  color: var(--a-bad);
  display: grid;
  place-items: center;
  font-size: 0.52em;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.doc__id { min-inline-size: 0; }
.doc__id b { display: block; font-size: 0.62em; font-weight: 600; color: var(--m-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.doc__id span { display: block; font-size: 0.55em; }
.doc__dl { color: var(--m-deep); flex: none; }
.doc__dl svg { inline-size: 1.05em; block-size: 1.05em; }

/* ---- A running total, under an order summary. ---- */
.sum { display: grid; gap: 0.3em; font-size: 0.62em; }
.sum__row { display: flex; align-items: baseline; gap: 0.5em; min-inline-size: 0; }
.sum__row span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sum__row b { margin-inline-start: auto; color: var(--m-ink); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sum__row--total {
  padding-block-start: 0.4em;
  border-block-start: 1px solid var(--a-line);
  font-size: 1.05em;
}
.sum__row--total b { font-size: 1.15em; }
.sum__note { font-size: 0.55em; }


/* ---- Narrow frames: fewer things, bigger.
   Below ~26rem of frame the 1.45cqw root em hits its 0.38rem floor and the
   whole app renders at ~6px, which is a texture rather than a screen. The
   fix is not to zoom a full dashboard down — it is to show less of it, the
   way the drawn marketing sites already drop their nav and their second
   column. Measured: at the 390px viewport the before/after frame is 374px
   wide, so every rule below fires there. ---- */
@container screen (max-width: 26rem) {
  .app { font-size: clamp(0.5rem, 2.3cqw, 0.78rem); }
  /* Four tiles in two rows eat the height the panels need. */
  .kpi > :nth-child(n + 3) { display: none; }
  /* A five-column table at this width is a texture, not a table. */
  .app__drop-narrow { display: none; }
  /* Long lists lose their tail rather than their legibility. */
  .tbl__row:nth-child(n + 6),
  .bars__row:nth-child(n + 5),
  .reo__item:nth-child(n + 4),
  .sync__logrow:nth-child(n + 5) { display: none; }
}

/* ============================================================
   7. PHONE RENDERING
   ------------------------------------------------------------
   Two class names on the root-em rule (.app.app--phone), for the
   same reason .msite.msite--phone carries two: any later layer
   that sets .app--phone at one class would win at equal
   specificity and hand the phone a desktop root em.
   ============================================================ */

.app.app--phone {
  font-size: clamp(0.46rem, 8.2cqw, 0.75rem);
  grid-template-columns: minmax(0, 1fr);
}
.app--phone .app__rail { display: none; }
.app--phone .app__main { grid-template-rows: auto auto minmax(0, 1fr); }
.app--phone .app__top { padding: 0.6em 0.8em; }
.app--phone .app__tools .app__search,
.app--phone .app__tools .app__lang { display: none; }
.app--phone .app__body { padding: 0.7em; gap: 0.55em; }
.app--phone .app__split { grid-template-columns: 1fr; }
.app--phone .app__split > :last-child { display: none; }
.app--phone .kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* The phone screen is a viewport, not a summary: a real portal
   shows one order, not the whole table. */
.app--phone .is-desk { display: none; }

/* The drawn app needs the same status strip the drawn sites get,
   or the Dynamic Island lands on the app's own top bar.
   .msite__status is reused verbatim — it reads --m-ink and
   --surface only, both of which .app--wadi provides. */
.app--phone .msite__status { background: var(--a-panel); }

/* The device. The shared layer's geometry rules are written for
   .msite--phone; the app phone is the same physical device, so
   it takes the same aspect ratio and radii. */
.showcase--product .stage__phone > .app--phone,
.ba__panel--after .ba__phone > .app--phone {
  position: relative;
  z-index: 1;
  aspect-ratio: 9 / 19.5;
  block-size: auto;
  border-radius: 1.3rem;
  overflow: hidden;
}
.ba__panel--after .ba__phone > .app--phone { border-radius: 1rem; }


/* ============================================================
   8. THE "BEFORE" PANEL'S SPREADSHEET
   ------------------------------------------------------------
   The Lead Engine site in the before panel is not broken — that
   is the point of this tier, and the drawing must not pretend
   otherwise. What is broken is behind it: the stock figures the
   site quotes live in a file that is emailed between branches.
   So the spreadsheet hangs off the before frame exactly where
   the phone hangs off the after frame, and the two panels read
   as a swap rather than a repair.
   ============================================================ */

@media (min-width: 30rem) {
  .ba__panel--before .ba__frame { padding-block-end: 3rem; }
}
.ba__aside {
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0.9rem;
  inline-size: clamp(8.5rem, 40%, 13.5rem);
  display: none;
}
@media (min-width: 30rem) { .ba__aside { display: block; } }

.sheet {
  background: #fff;
  border-radius: 0.4rem;
  overflow: hidden;
  box-shadow: 0 20px 40px -16px rgba(2, 7, 37, 0.4), 0 0 0 1px rgba(2, 7, 37, 0.1);
  font-family: var(--font-body);
  container-type: inline-size;
  font-size: clamp(0.34rem, 4.4cqw, 0.62rem);
  line-height: 1.4;
}
[lang="ar"] .sheet { font-family: var(--font-arabic); }
.sheet__bar {
  display: flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.5em 0.7em;
  background: #1e7145;   /* the green every spreadsheet wears */
  color: #fff;
  min-inline-size: 0;
}
.sheet__bar svg { inline-size: 1.1em; block-size: 1.1em; flex: none; }
.sheet__name {
  font-size: 0.82em;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* A filename is a Latin string even in the Arabic build, and it
     is the joke — keep it LTR so v7 (2) does not reorder. */
  direction: ltr;
  unicode-bidi: isolate;
}
.sheet__grid { display: grid; font-size: 0.8em; }
.sheet__row {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr));
  border-block-end: 1px solid #e6e8ea;
}
.sheet__row > * {
  padding: 0.4em 0.5em;
  border-inline-end: 1px solid #e6e8ea;
  min-inline-size: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #3c454f;
  font-variant-numeric: tabular-nums;
}
.sheet__row > :last-child { border-inline-end: 0; }
.sheet__row--head > * { background: #eef1f3; font-weight: 600; color: #1f2933; font-size: 0.92em; }
.sheet__row:last-child { border-block-end: 0; }
.sheet__cell--edit { background: #fff7d6; box-shadow: inset 0 0 0 1.5px #d9a400; color: #1f2933; font-weight: 600; }
.sheet__foot {
  padding: 0.45em 0.7em;
  background: #f5f7f8;
  border-block-start: 1px solid #e6e8ea;
  font-size: 0.74em;
  color: #7a838d;
  display: flex;
  align-items: center;
  gap: 0.35em;
  min-inline-size: 0;
}
.sheet__foot svg { inline-size: 1em; block-size: 1em; flex: none; color: #b26a06; }
.sheet__foot span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The before panel sits back on the other two pages by shadow
   alone; the spreadsheet is the loudest thing in it, so it takes
   the recession instead of a highlight. */
.ba__panel--before .ba__aside { filter: saturate(0.82); }


/* ============================================================
   9. HERO — DIGITAL OPERATIONS
   ------------------------------------------------------------
   The tier's hero shows an app, not a site, so the browser frame
   is doing less work than on the other two pages: there is no
   marketing page to recognise, only a screen to read. The phone
   therefore carries the portal rather than a second view of the
   same page.
   ============================================================ */

/* The signed-in URL. A path with an order reference in it is the
   fastest way to say "this is behind a login" without a badge. */
.stage__url .stage__lock {
  display: inline-flex;
  align-items: center;
  vertical-align: -0.15em;
  margin-inline-end: 0.35em;
  color: var(--success);
}
.stage__url .stage__lock svg { inline-size: 0.85em; block-size: 0.85em; }


/* ============================================================
   10. SNIPPETS — "What's included"
   ------------------------------------------------------------
   Same contract as the Trade Presence and Lead Engine snippets:
   a scrap of real interface per group, drawn in the SITE's
   tokens rather than the demo brand's, sitting in the shared
   `.snip` frame. They are recognisable at a glance and carry no
   text, so they need no translation and mirror for free.
   ============================================================ */

/* portals: a rail and two accounts, each seeing a different thing */
.snip__portal { display: grid; grid-template-columns: 0.5rem 1fr; gap: 0.4rem; align-items: stretch; }
.snip__portal .rail {
  border-radius: 0.15rem;
  background: var(--brand-primary);
  min-block-size: 2.4rem;
}
.snip__portal .rows { display: grid; gap: 0.3rem; align-content: center; }
.snip__portal .row { display: flex; align-items: center; gap: 0.3rem; }
.snip__portal .who {
  inline-size: 0.7rem;
  block-size: 0.7rem;
  border-radius: var(--radius-full);
  background: var(--brand-accent);
  flex: none;
}
.snip__portal .row:last-child .who { background: var(--brand-primary-light); }
.snip__portal .bar {
  block-size: 0.3rem;
  border-radius: 1px;
  background: var(--border);
  flex: 1;
}
.snip__portal .row:last-child .bar { max-inline-size: 62%; }

/* dashboards: one number and the bars under it */
.snip__dash { display: grid; gap: 0.35rem; }
.snip__dash .tile {
  display: flex;
  align-items: flex-end;
  gap: 0.3rem;
}
.snip__dash .num {
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}
.snip__dash .cap { block-size: 0.3rem; inline-size: 1.6rem; border-radius: 1px; background: var(--border); margin-block-end: 0.15rem; }
.snip__dash .bars { display: grid; gap: 0.22rem; }
.snip__dash .bars i {
  block-size: 0.32rem;
  border-radius: var(--radius-full);
  background: var(--brand-primary);
  display: block;
}
.snip__dash .bars i:nth-child(1) { inline-size: 88%; }
.snip__dash .bars i:nth-child(2) { inline-size: 64%; }
.snip__dash .bars i:nth-child(3) { inline-size: 34%; background: var(--brand-accent); }

/* integrations: two systems and the wire between them */
.snip__wire { display: flex; align-items: center; gap: 0.3rem; }
.snip__wire .node {
  flex: 1;
  block-size: 1.6rem;
  border-radius: 0.25rem;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--border);
  display: grid;
  place-items: center;
  color: var(--text-muted);
}
.snip__wire .node svg { inline-size: 0.85rem; block-size: 0.85rem; }
.snip__wire .node--site { color: var(--brand-primary); }
.snip__wire .node--site { background: color-mix(in srgb, var(--brand-primary) 12%, var(--surface)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--brand-primary) 35%, transparent); }
.snip__wire .link {
  inline-size: 1.1rem;
  block-size: 0;
  border-block-start: 2px dashed var(--brand-accent);
  flex: none;
}

/* carried over: the four Lead Engine systems, each ticked off.
   Four blank pills read as decoration; four ticks read as a list of
   things that are already done, which is the point of the group. */
.snip__carry { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.snip__carry span {
  display: grid;
  place-items: center;
  block-size: 1.1rem;
  inline-size: 1.1rem;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--success) 14%, var(--surface));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--success) 38%, transparent);
  color: var(--success);
}
.snip__carry span svg { inline-size: 0.7rem; block-size: 0.7rem; }
