﻿/* ════════════════════════════════════════════════════════════════════════════
   Petromix Field — stylesheet.

   PALETTE IS FIXED. Six hex codes, no invented alternatives:
     #F7A11A amber    #F47B0B vivid    #FFFFFF white
     #232323 charcoal #2B2118 brown    #8F9AA3 steel

   ONE deviation, and it is deliberate: orange fills carry CHARCOAL ink, never
   white. Measured — white on these oranges is 2.09–3.11:1 against a 4.5:1
   requirement; charcoal on the same fills is 5.75–7.53:1. No new colour is
   introduced, only a different pairing of two that were already mandated.
   ════════════════════════════════════════════════════════════════════════════ */

/* ══ THEME BRIDGE ═══════════════════════════════════════════════════════════
   The same move already made in manager.css. These names used to hold literal
   colours; they now POINT AT theme.css, which is what makes all 828 rule
   blocks follow light and dark without being edited.

   It works because the names describe a COLOUR while the code uses them for a
   ROLE. Counted across this file: --white appears 48 times as a foreground
   against 1 as a background, --brown 10 times as a background and never as a
   foreground, --steel 108 times as a foreground, --line 52 times as a border
   and nothing else. Each is re-pointed at the theme token for the role it was
   already filling.

   Four declarations broke that rule and were fixed by hand first: a map region
   stroke, the bottom-sheet grip, the calendar "today" cell and its peak ring.

   Old literals are kept in the comments so the mapping stays auditable.
   New work uses the theme tokens directly; this block carries the code that
   predates them. */
:root {
  /* Accent. Amber is the brand in both themes. */
  --amber:     var(--accent);            /* was #F7A11A */
  --vivid:     var(--accent-hover);      /* was #F47B0B */
  --grad-top:  #F58A1F;                  /* amber gradient, identical in both */
  --grad-bot:  #E8700A;

  /* Foreground roles. */
  --white:     var(--ink);               /* was #FFFFFF — text, 48 uses */
  --steel:     var(--ink-subtle);        /* was #8F9AA3 — muted text, 108 uses */

  /* Surface roles. --panel loses its translucency: it was rgba(35,35,35,.82)
     with a backdrop blur on every card, which is a real mobile paint cost and
     is not how the reference builds depth. Glass now lives only on the fixed
     chrome, where content genuinely scrolls underneath. */
  --brown:     var(--canvas);            /* was #2B2118 — page ground, 10 uses */
  --charcoal:  var(--e1-bg);             /* was #232323 — raised surface */
  --panel:     var(--e1-bg);             /* was rgba(35,35,35,.82) */

  /* Borders. */
  --line:      var(--hairline);          /* was rgba(143,154,163,.22) — 52 uses */
  --line-soft: var(--hairline);          /* was rgba(143,154,163,.13) */

  /* Typography now resolves to the self-hosted Inter and JetBrains Mono.
     The old comment here warned that the typeface used to change on sign-in;
     auth.html moves to the same two faces in this pass, so it still holds. */
  --ui:   var(--font-ui);
  --mono: var(--font-mono);

  /* Layout constants. Not colours, not themed. --r keeps its name for the
     code that already uses it but now resolves to the radius scale. */
  --r:        var(--r-lg);               /* was 16px */
  --rail-w:   248px;
  --tap:      48px;                      /* thumb-target floor */

  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
}
/* --on-accent is deliberately NOT bridged: it is the ink that sits on an amber
   fill and must stay dark in BOTH themes. theme.css owns it. Bridging it to
   --charcoal would turn every button label white-on-amber in light mode. */

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html { height: 100%; }

body {
  margin: 0;
  /* 100% rather than 100vw, deliberately.

     `100vw` is the viewport INCLUDING the scrollbar, so as soon as a vertical
     scrollbar appears the body is ~15px wider than the space actually visible.
     Paired with `overflow-x: hidden` below, that does not scroll — it silently
     CLIPS the right edge, which is what was cutting the second column of cards
     in half. `100%` resolves against the available width and cannot do that. */
  width: 100%;
  height: 100dvh;
  /* Was a hard-coded #232323 with three animated amber radial gradients. Two
     problems, and the theme only exposed the first:

     1. It ignored the token layer entirely, so the page stayed charcoal in
        light mode while the chrome around it went white.
     2. `animation: ambientWave 15s infinite` animated BACKGROUND-POSITION on a
        full-screen gradient, forever. That is a continuous full-viewport
        repaint on a phone that a rep holds all day, it is the single most
        expensive thing on the page, and the design skill bans exactly this
        (§6.A: animate transform and opacity only; §5: no perpetual motion
        without a reason).

     The canvas is now flat and themed. The amber tint survives as a single
     static wash so the ground is not dead grey. */
  /* Flat. The amber wash that used to live here moved into the ambient
     background layer (theme.css .bgfx), which animates it properly. Keeping
     both stacked two sets of blobs on top of each other. */
  background-color: var(--canvas);
  overflow-x: hidden;
}

@keyframes ambientWave {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* iOS below 16.4 does not support dvh; these sit underneath as fallbacks and
   are overridden by the dvh rule above wherever it is supported. */
@supports not (height: 100dvh) {
  body { height: 100vh; height: -webkit-fill-available; }
}

body {
  color: var(--white);
  font: 16px/1.5 var(--ui);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;      /* no rubber-band on iOS */
  touch-action: manipulation;     /* no 300ms tap delay */
}

h1, h2, h3 { margin: 0; font-weight: 800; letter-spacing: -0.01em; }
button, input, select, textarea { font: inherit; color: inherit; }

/* ── Shell ────────────────────────────────────────────────────────────────── */
.app {
  display: grid;
  height: 100%;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas: "topbar" "content" "rail";
  overflow: hidden;                /* only .content scrolls */
}
/* The shell guards itself rather than relying on every child remembering to.
   Anything dropped into this grid later inherits the protection. */
.app > * { min-width: 0; }

.topbar  { grid-area: topbar; }
.content { grid-area: content; }
.rail    { grid-area: rail; }

.topbar {
  /* Positioned and raised so the notification panel hanging out of it paints
     OVER .content. backdrop-filter below already makes this a stacking context,
     and .content is later in the DOM, so without a z-index here the page
     content drew on top of an open panel. */
  position: relative; z-index: 30;
  display: flex; align-items: center; gap: 10px;
  padding: calc(var(--safe-t) + 10px) calc(var(--safe-r) + 16px) 10px calc(var(--safe-l) + 16px);
  /* Was rgba(43,33,24,.72), a fixed translucent brown that stayed brown over a
     white page. --glass is the canvas with alpha, so the bar reads as the page
     dimmed rather than as a foreign material. */
  background: var(--glass);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}
.topbar__spacer { flex: 1; }

.topbar__who { min-width: 0; flex: 1 1 auto; }   /* takes the room; the spacer only pushes when there is spare */
.topbar__name {
  margin: 0; font-size: 15px; font-weight: 800; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The rep's manager, always on screen. A rep needs to know whose team their
   numbers land in without opening a menu to find out. */
.topbar__mgr {
  margin: 1px 0 0; font-size: 11px; color: var(--steel); line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* A phone has no room for one long line: the name and the manager wrap (two lines at most) instead of "Omar G…"
   (v4.240, the layout audit and the user's own screenshot). */
@media (max-width: 640px) {
  .topbar__name, .topbar__mgr { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow-wrap: anywhere; }
}

/* ── Sync badge ───────────────────────────────────────────────────────────── */
.sync {
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  padding: 5px 10px; border-radius: 99px;
  border: 1px solid var(--success-wash); background: var(--success-wash);
  font-size: 10.5px; font-weight: 800; letter-spacing: .04em; color: var(--success);
  transition: background .2s ease, border-color .2s ease, color .2s ease;
}
.sync__dot {
  width: 7px; height: 7px; border-radius: 50%; background: currentColor;
  animation: syncPulse 2.4s ease-in-out infinite;
}
@keyframes syncPulse { 0%,100% { opacity: .5; } 50% { opacity: 1; } }

/* Offline is a state the rep must not miss — this app is used in plant
   corridors where signal drops constantly, and a quote typed while offline
   has to be understood as not-yet-sent. */
.sync.is-off {
  border-color: rgba(143,154,163,.5); background: rgba(143,154,163,.14); color: var(--steel);
}
.sync.is-off .sync__dot { animation: none; }
/* Something is waiting to reach the server, or was refused (v4.134). */
.sync.is-wait { border-color: rgba(245,165,36,.45); background: rgba(245,165,36,.14); color: #F5B54A; }
.sync.is-fail { border-color: rgba(242,119,124,.5); background: rgba(242,119,124,.14); color: #F2777C; }
.sync.is-wait .sync__dot, .sync.is-fail .sync__dot { animation: none; }
:root[data-scheme="light"] .sync.is-wait { color: #8A5A00; }
:root[data-scheme="light"] .sync.is-fail { color: #B42318; }
@media (max-width: 380px) { .sync:not(.is-wait):not(.is-fail) .sync__txt { display: none; } }

.iconbtn {
  width: var(--tap); height: var(--tap); flex: none;   /* a long name never squeezes them (v4.240: 21 px wide) */
  display: grid; place-items: center;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--white);
  cursor: pointer; position: relative;
}
.iconbtn:hover { background: var(--wash); }
.iconbtn svg { width: 21px; height: 21px; fill: none; stroke: currentColor; stroke-width: 1.9;
               stroke-linecap: round; stroke-linejoin: round; }

/* ── notification bell ─────────────────────────────────────────────────────
   The wrapper is the positioning context, so the panel hangs off the bell and
   not off the topbar — the topbar clips nothing, but its backdrop-filter makes
   it a containing block, and a panel positioned against that drifts on a phone
   where the safe-area padding changes. */
.bell { position: relative; flex-shrink: 0; }

.bell__count {
  position: absolute; top: 4px; inset-inline-end: 4px;
  min-width: 17px; height: 17px; padding: 0 4px;
  display: grid; place-items: center;
  border-radius: 9px; border: 2px solid #2b2118;
  background: var(--red, #e2604b); color: #fff;
  font-size: 10px; font-weight: 800; font-style: normal; line-height: 1;
}
/* `display:grid` above is an AUTHOR rule, and author rules beat the user
   agent's `[hidden] { display: none }` whatever their specificity. Without
   this the badge sat there reading "0" with nothing waiting. */
.bell__count[hidden], .bell__panel[hidden] { display: none; }

/* A quiet pulse the first time it appears, then still. A badge that pulses
   forever is a badge people stop seeing. */
.bell__btn.has-new svg { animation: bellRing .6s ease 1; transform-origin: 50% 15%; }
@keyframes bellRing {
  0%,100% { transform: rotate(0); } 20% { transform: rotate(11deg); }
  45% { transform: rotate(-9deg); } 70% { transform: rotate(5deg); }
}
@media (prefers-reduced-motion: reduce) { .bell__btn.has-new svg { animation: none; } }

.bell__panel {
  position: absolute; top: calc(100% + 8px); inset-inline-end: 0; z-index: 60;
  width: min(330px, calc(100vw - 32px));
  max-height: min(60vh, 420px); overflow-y: auto;
  padding: 6px;
  border: 1px solid var(--line); border-radius: 14px;
  background: #35281d; color: var(--white);
  box-shadow: 0 18px 44px var(--shadow-color);
}
/* On a phone a 330px panel anchored to a bell that is itself ~90px from the
   right edge runs off the left of the screen — measured, the heading read
   "OTIFICATIONS". Dropping the wrapper's positioning hands the panel to the
   topbar instead, so it spans the screen with a gutter either side. */
@media (max-width: 560px) {
  .bell { position: static; }
  .bell__panel {
    width: auto;
    inset-inline: calc(var(--safe-l) + 12px) calc(var(--safe-r) + 12px);
    top: calc(100% - 6px);
  }
}

.bell__h {
  margin: 4px 8px 8px; font-size: 12px; font-weight: 800;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-subtle);
}
.bell__h em {
  font-style: normal; margin-inline-start: 4px; padding: 1px 6px;
  border-radius: 8px; background: var(--red, #e2604b); color: #fff;
}
.bell__i {
  width: 100%; display: grid; gap: 10px; align-items: start;
  grid-template-columns: 26px 1fr auto;
  padding: 9px 8px; margin-bottom: 2px;
  border: 0; border-radius: 10px; background: transparent;
  color: inherit; text-align: start; cursor: pointer;
}
.bell__i:hover { background: var(--wash); }
.bell__ico {
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--wash);
}
.bell__ico svg { width: 14px; height: 14px; fill: none; stroke: currentColor;
                 stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.bell__i.is-won   .bell__ico { background: rgba(111,207,151,.18); color: #6fcf97; }
.bell__i.is-lost  .bell__ico { background: rgba(226,96,75,.18);  color: #e2604b; }
.bell__i.is-reply .bell__ico { background: rgba(247,161,26,.18); color: #f7a11a; }
.bell__tx { min-width: 0; display: block; }
.bell__tx b { display: block; font-size: 13px; font-weight: 700; line-height: 1.35; }
.bell__tx i {
  display: block; font-style: normal; font-size: 11.5px; color: var(--ink-subtle); line-height: 1.4;
  overflow-wrap: anywhere;   /* the whole line, wrapped (v4.240: "They cannot open the app until you appro…") */
}
.bell__w { font-size: 10.5px; color: var(--ink-tertiary); white-space: nowrap; padding-top: 2px; }
.bell__empty { margin: 6px 8px 10px; font-size: 12.5px; line-height: 1.5; color: var(--ink-subtle); }
.bell__all {
  width: 100%; margin-top: 4px; padding: 9px;
  border: 0; border-radius: 10px;
  background: var(--amber); color: var(--on-accent);
  font-size: 12.5px; font-weight: 800; cursor: pointer;
}

.avatar {
  width: 38px; height: 38px; border-radius: 50%;
  display: grid; place-items: center; flex-shrink: 0;
  background: var(--amber); color: var(--on-accent);
  font-size: 13px; font-weight: 800; letter-spacing: .02em;
}

.content {
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 16px calc(var(--safe-r) + 16px) 28px calc(var(--safe-l) + 16px);
  display: flex; flex-direction: column; gap: 14px;
  min-width: 0;
}
/* Two different defaults bite here, on two different axes.

   CROSS AXIS: flex items default to min-width:auto and refuse to shrink below
   their content, so the horizontally-scrolling chips row pushed the whole
   column wider instead of scrolling inside it.

   MAIN AXIS: flex items also default to flex-shrink:1. Normally min-height:auto
   protects them — but for a SCROLL CONTAINER that automatic minimum resolves to
   zero, so `.chips` (overflow-x:auto) could be squashed to a sliver whenever the
   column ran short of room. That is what flattened it to a few pixels of orange.
   The column scrolls; its children keep their natural height. */
.content > * { min-width: 0; max-width: 100%; flex-shrink: 0; }

/* ── Nav ──────────────────────────────────────────────────────────────────── */
/* ══ FLOATING NAV ═══════════════════════════════════════════════════════════
   The reference's bottom bar is a detached rounded slab with the page visible
   either side of it, not a strip welded to the screen edge. That one change
   does more for the "modern app" read than any amount of colour.

   This is the one place backdrop-filter stays: it is a small, fixed element
   that content genuinely scrolls underneath, which is the case the effect was
   designed for and is cheap. The cost was never the blur, it was applying one
   to every card in a scrolling list. */
.rail {
  display: flex; flex-direction: column;
  margin: 0 calc(var(--safe-l) + 12px) calc(var(--safe-b) + 12px) calc(var(--safe-r) + 12px);
  border-radius: var(--r-2xl);
  background: var(--glass);
  backdrop-filter: blur(20px) saturate(140%); -webkit-backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-2);
  overflow: hidden;
}
/* `.rail` prefix so these actually win. Unprefixed, `.rail__cta` (0,1,0) tied
   with `.btn { display: inline-flex }` (0,1,0) and lost on source order,
   because .btn is declared later in this file. The result was a SECOND "View
   Products" button riding the bottom bar on every phone screen, duplicating
   the one already on Home. The design skill bans duplicate CTA intent, and it
   was only invisible because it sat outside the bar's chrome; with the bar
   floating it became obvious. */
.rail .rail__brand,
.rail .rail__cta,
.rail .rail__foot { display: none; }
.rail__nav { display: flex; }

.navitem {
  flex: 1; min-height: var(--tap);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  padding: 7px 4px; border: 0; background: none;
  color: var(--ink-subtle); font-size: 11px; font-weight: 500; cursor: pointer;
  transition: color var(--dur-fast) var(--ease);
}
.navitem svg { width: 21px; height: 21px; fill: none; stroke: currentColor; stroke-width: 1.8;
               stroke-linecap: round; stroke-linejoin: round; }
/* --accent-ink, not --accent: raw amber is 1.9:1 on a white rail and fails
   WCAG AA. The token darkens in light mode and stays amber in dark. */
.navitem.is-active { color: var(--accent-ink); font-weight: 600; }
/* Feedback on tap. There is no hover on a phone, so this is the only signal
   the rep gets that the tab registered. */
.navitem:active { transform: scale(var(--press)); transition-duration: var(--dur-fast); }
/* A phone: seven tabs must all fit. Each took the width of its longest label,
   so at 375 px "Equivalents" pushed Settings off the end of the bar (cut to
   "Setti…"). Equal slots, a smaller label; "Live Orders" wraps as before. */
@media (max-width: 420px) {
  .navitem { flex: 1 1 0; min-width: 0; padding: 6px 0; font-size: 10px; }
  .navitem[data-tab="equiv"] { flex-grow: 1.3; }    /* the longest label gets the room it needs */
}

/* ── Live Orders sub-menu ─────────────────────────────────────────────────────
   Live Orders opens its six sections instead of navigating. One list, painted
   into two places by paintLoNav(): #loSub expands inline in the laptop rail,
   #loPop pops up over the phone's bottom bar. Closed is display:none through a
   class, never the [hidden] attribute — an author display rule beats the UA's
   [hidden] (E-03). */
.navsub { display: none; }
.navitem__chev { display: none; }
.navsub__i {
  display: flex; align-items: center; gap: 10px; width: 100%;
  min-height: 44px; padding: 0 12px; border: 0; border-radius: 10px;
  background: none; color: var(--ink-subtle); font: 500 14px var(--ui);
  cursor: pointer; text-align: start;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.navsub__i svg {
  width: 17px; height: 17px; flex: none; fill: none; stroke: currentColor;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.navsub__i span { flex: 1 1 auto; min-width: 0; overflow-wrap: break-word; line-height: 1.25; }   /* "Smart Ad…" in the sidebar: wraps now (v4.240) */
.navsub__i em { font-style: normal; font-family: var(--mono); font-size: 11px; color: var(--ink-subtle); flex: none; }
.navsub__i:hover { background: var(--wash); color: var(--ink); }
.navsub__i.is-on { background: var(--accent-wash); color: var(--accent-ink); font-weight: 600; }
.navsub__i.is-on em { color: var(--accent-ink); }
.navsub__i:focus-visible { outline: 2px solid var(--accent-focus); outline-offset: 1px; }

/* Phone: a menu card above the bottom bar, the width of the bar. */
@media (max-width: 1023px) {
  .navsub--pop.is-open {
    display: flex; flex-direction: column; gap: 2px;
    position: fixed; z-index: 60;
    inset-inline: calc(var(--safe-l) + 12px) calc(var(--safe-r) + 12px);
    bottom: calc(var(--safe-b) + 12px + var(--tap) + 26px);
    padding: 6px; border-radius: var(--r-xl, 18px);
    background: var(--e3-bg); border: 1px solid var(--hairline-strong);
    box-shadow: var(--shadow-2);
  }
}
/* Laptop: an indented list under Live Orders, with a chevron that turns. */
@media (min-width: 1024px) {
  .navsub--pop { display: none !important; }
  /* Six more rows can outgrow a short window; the nav scrolls rather than
     clipping under the rail's overflow:hidden. */
  .rail__nav { min-height: 0; overflow-y: auto; }
  .navitem__chev {
    display: block; width: 16px !important; height: 16px !important;
    margin-inline-start: auto; opacity: .6; transition: transform var(--dur-fast) var(--ease);
  }
  .navitem.is-open .navitem__chev { transform: rotate(180deg); }
  .navsub.is-open {
    display: flex; flex-direction: column; gap: 2px;
    margin-block: 2px 6px; margin-inline-start: 24px; padding-inline-start: 10px;
    border-inline-start: 1px solid var(--hairline-strong);
  }
  .navsub__i { min-height: 38px; font-size: 13.5px; }
}

/* ── Panels & type ────────────────────────────────────────────────────────── */
.panel {
  position: relative;
  background: var(--e1-bg);
  border: 1px solid var(--e1-border);
  box-shadow: var(--shadow-1);
  border-radius: var(--r-lg);
  padding: var(--space-4);
  /* backdrop-filter removed. It ran on EVERY panel, and a blur behind a
     scrolling list is one of the most expensive things a phone GPU can be
     asked to do continuously. The elevation ladder gives the same separation
     for free, and the reference builds depth this way anyway. */
}
.kicker {
  margin: 0 0 6px; font-size: 11.5px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--steel);
}
.h2 { font-size: 17px; margin-bottom: 14px; }

/* ── Dashboard ────────────────────────────────────────────────────────────────
   The reference layout — big title with inline stats, then a 2x2 card grid —
   in Petromix's own charcoal and amber rather than the reference's light blue.
   The ambient background still shows through the cards. */
/* One column on a phone; the 2x2 of the reference from tablet up. minmax(0,1fr)
   because an SVG in a bare 1fr track takes its intrinsic width as a minimum and
   refuses to shrink, which breaks the split exactly as it did on the manager's
   dashboard. */
.dash { display: grid; gap: 14px; grid-template-columns: 1fr; min-width: 0; }
@media (min-width: 760px) {
  .dash { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* ══ REP APP CARDS, premium pass ════════════════════════════════════════════
   Same treatment as the manager dashboard so the two halves of the product
   read as one app: fill-contrast separation, a near-invisible border, a
   top-lit sheen, and lift on hover with a press on tap.

   backdrop-filter is gone here too. It was blurring whatever sat behind every
   card on a scrolling list, which is the most expensive thing a phone GPU can
   be asked to do continuously, and the widened surface ladder now does the
   separating on its own. */
.dcard {
  position: relative;
  background: var(--e1-bg); border: 1px solid var(--e1-border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-4) 18px 18px; min-width: 0;
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
  /* A card is a column so its body can grow into the height the grid row
     settled on. Grid already stretched the CARD; without this the content sat
     at the top and the card next to it looked taller than its neighbour. */
  display: flex; flex-direction: column;
  /* And it is a query container, so anything inside asks how wide the CARD is
     rather than how wide the window is. In the 2-up layout a 760px window is a
     ~360px card — a viewport query here is off by a factor of two. */
  container-type: inline-size;
}
/* The sheen rides a pseudo-element so the card's own background stays a plain
   token and the two cannot fight. */
.dcard::before {
  content: ''; position: absolute; inset: 0;
  border-radius: inherit; pointer-events: none; z-index: 0;
  background: var(--sheen);
}
.dcard > * { position: relative; z-index: 1; }
.dcard:hover {
  transform: translateY(var(--lift));
  box-shadow: var(--shadow-2);
  border-color: var(--hairline-strong);
}
.dcard:active { transform: translateY(0) scale(var(--press));
                transition-duration: var(--dur-fast); }

.dcard > :not(.dcard__head) { flex: 1 1 auto; min-height: 0; }
.dcard--wide { grid-column: 1 / -1; }
.dcard--bare { padding: 0; overflow: hidden; }
.dcard__head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 12px; min-width: 0; }
.dcard__head h2 { font-size: 14.5px; font-weight: 800; margin: 0; min-width: 0;
                  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dcard__note { font-size: 11px; color: var(--steel); margin-left: auto;
               font-family: var(--mono); white-space: nowrap; }

/* ── Proposals + Follow-ups row ──────────────────────────────────────────────
   The supplied design's own grid: two equal columns while each card gets
   480px, stacked below that. Declared after .dash so it wins that rule's
   two-column split at 760px, which would squeeze the calendar into ~360px. */
.dash--fu {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 480px), 1fr));
  gap: 20px; align-items: stretch;
}

/* Proposals by status: proposals-card.css draws the card, border and corners
   included, so the .dcard around it is only a grid cell. */
.dcard--ps { padding: 0; border: 0; background: none; box-shadow: none; display: flex; min-width: 0; }
.dcard--ps:hover { transform: none; box-shadow: none; }
.ps-host, .ps-host > .ps { flex: 1; min-width: 0; }
.ps-host { display: flex; flex-direction: column; }   /* so the card fills the row's height */

/* The header panel: dashboard-header.css draws it; the host only spaces it. */
.dh-host { margin-bottom: 4px; min-width: 0; }

/* Follow-ups: the same — follow-ups.css draws the card. */
.dcard--fuh { padding: 0; border: 0; background: none; box-shadow: none; display: flex; min-width: 0; }
.dcard--fuh:hover, .dcard--fuh:active { transform: none; box-shadow: none; }
.fu-host, .fu-host > .fu { flex: 1; min-width: 0; }
.fu-host { display: flex; flex-direction: column; }



/* Trend */

/* ── Clients near me · radar ───────────────────────────────────────────────────
   The supplied design, implemented to its own values. It runs its own palette
   (var(--e1-bg) ground, var(--accent) amber, var(--ink) cream) rather than the app tokens,
   because it was specified that way — the tokens are deliberately not
   substituted here.

   The one adaptation is responsive: the design is a fixed 1fr + 400px split,
   which cannot hold on a phone, so below 1080px the two halves stack. Nothing
   else is retuned. */
/* Spanning the row is all --wide means. Dropping the padding is --bare's job:
   this rule used to do both, which stripped the padding off the Proposal trend
   card too — wide, but with no ground of its own to sit on. */
.dcard--wide { width: 100%; min-width: 0; }
/* --bare: the block brings its own ground, so the card chrome gets out of its
   way entirely. */
.dcard--bare { border-color: var(--wash-strong); }
.dcard--bare > .dcard__head { padding: 16px 18px 0; }

.rdr {
  font-family: var(--ui);
  background: var(--e1-bg); color: var(--ink);
  display: flex; flex-direction: column; min-width: 0;
}

/* — header — */
.rdr__top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; padding: 20px 32px; flex-wrap: wrap;
}
.rdr__brand { display: flex; align-items: center; gap: 18px; min-width: 0; }
/* The real P, cropped from the lockup. It was a clip-path polygon, then a
   hand-drawn SVG — both because an image was assumed to be a network
   dependency. logo.png is precached by the service worker, so it is not. */
.rdr__mark { height: 34px; flex: none; }
.rdr__rule { width: 2px; height: 30px; background: var(--accent-wash); flex: none; }
.rdr__title { font-weight: 800; font-size: 20px; letter-spacing: -.02em; min-width: 0; }

.rdr__meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rdr__k {
  font-size: 11px; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-subtle);
}
.rdr__origin {
  font-size: 13px; font-weight: 700; color: var(--ink);
  border: 2px solid var(--wash-strong); padding: 7px 12px; white-space: nowrap;
}
.rdr__live {
  display: flex; align-items: center; gap: 8px;
  font-size: 11px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: var(--accent-ink); border: 2px solid var(--accent-wash); padding: 8px 12px;
}
.rdr__livedot { width: 8px; height: 8px; background: var(--accent); display: block; flex: none; }

.rdr__hr { height: 2px; background: var(--wash-strong); flex: none; }

/* — the split — */
.rdr__grid { flex: 1; display: grid; grid-template-columns: minmax(0, 1fr); min-width: 0; }
@media (min-width: 1080px) {
  .rdr__grid { grid-template-columns: minmax(0, 1fr) 400px; }
  .rdr__side { border-left: 2px solid var(--wash-strong); border-top: 0; }
}

/* — stage — */
.rdr__stage {
  position: relative; display: flex; align-items: center; justify-content: center;
  padding: 56px 40px 72px; min-height: 560px; overflow: hidden; min-width: 0;
}
.rdr__mesh {
  position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(var(--wash) 1px, rgba(0,0,0,0) 1px),
    linear-gradient(90deg, var(--wash) 1px, rgba(0,0,0,0) 1px);
  background-size: 48px 48px;
}
.rdr__bloom {
  position: absolute; left: 50%; top: 50%; width: 900px; height: 900px;
  transform: translate(-50%, -50%); pointer-events: none;
  background: radial-gradient(circle, var(--accent-wash) 0%, rgba(251,176,28,0) 62%);
}

.rdr__scope { position: relative; width: min(540px, 100%); aspect-ratio: 1 / 1; flex: none; }
.rdr__disc {
  position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle at 50% 46%, #17140F 0%, #0B0907 74%);
  box-shadow: inset 0 0 90px rgba(0,0,0,.9), 0 0 0 2px var(--accent-wash);
}
.rdr__ring {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  border-radius: 50%; border: 1px solid; pointer-events: none;
}
.rdr__spoke {
  position: absolute; left: 50%; top: 50%; width: 1px; height: 100%; pointer-events: none;
  background: linear-gradient(180deg, rgba(251,176,28,0) 0%, var(--accent-wash) 46%,
                              var(--accent-wash) 54%, rgba(251,176,28,0) 100%);
}

.rdr__clip { position: absolute; inset: 0; border-radius: 50%; overflow: hidden; pointer-events: none; }
.rdr__sweep {
  position: absolute; inset: -2px; border-radius: 50%; will-change: transform;
  background: conic-gradient(from 0deg,
    var(--accent-wash) 0deg, var(--accent-wash) 22deg,
    var(--accent-wash) 46deg, rgba(251,176,28,0) 72deg, rgba(251,176,28,0) 360deg);
}
.rdr__beam {
  position: absolute; left: 50%; top: 0; width: 2px; height: 50%;
  transform-origin: 50% 100%; will-change: transform;
  background: linear-gradient(180deg, rgba(251,176,28,0) 0%, var(--accent-wash) 100%);
}

.rdr__bearing {
  position: absolute; transform: translate(-50%, -50%);
  font-size: 12px; font-weight: 800; letter-spacing: .14em;
}

/* — pins — 44px of hit area around a 6px dot, which is the smallest target a
   thumb finds reliably. */
.rdr__pin {
  position: absolute; width: 44px; height: 44px; margin: -22px 0 0 -22px;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.rdr__pin:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 50%; }
.rdr__pinring, .rdr__pinping {
  position: absolute; width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--accent);
}
.rdr__pindot { position: absolute; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }

.rdr__self {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 46px; height: 46px; display: flex; align-items: center; justify-content: center;
}
.rdr__selfpulse {
  position: absolute; width: 46px; height: 46px; border-radius: 50%;
  border: 2px solid var(--wash-strong);
}
.rdr__selfdot {
  position: absolute; width: 18px; height: 18px; border-radius: 50%;
  background: var(--ink); box-shadow: 0 0 18px var(--wash-strong);
}

.rdr__scale {
  position: absolute; left: 50%; bottom: -46px; transform: translateX(-50%);
  display: flex; gap: 22px; white-space: nowrap;
  font-size: 11px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-tertiary);
}

/* — side panel — */
.rdr__side {
  display: flex; flex-direction: column; min-width: 0;
  border-top: 2px solid var(--wash-strong);
}
.rdr__count { padding: 22px 26px 18px; }
.rdr__countrow { display: flex; align-items: baseline; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.rdr__big {
  font-weight: 800; font-size: 44px; line-height: 1; letter-spacing: -.03em; color: var(--accent-ink);
}
.rdr__of { font-size: 15px; font-weight: 500; color: var(--ink-subtle); }

.rdr__list { flex: 1; }
.rdr__row {
  display: flex; align-items: center; gap: 16px; padding: 16px 26px;
  border-bottom: 1px solid var(--wash-strong); cursor: pointer;
  transition: background 160ms ease; min-width: 0;
}
.rdr__row[data-c="-1"] { cursor: default; }
.rdr__row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.rdr__bullet {
  width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--accent); flex: none;
}
.rdr__bullet.is-off { border-color: #4A463F; }
.rdr__rowmain { flex: 1; min-width: 0; }
.rdr__name {
  font-weight: 700; font-size: 15px; letter-spacing: -.01em; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rdr__name.is-off { color: var(--ink-tertiary); }
.rdr__city { font-size: 12px; font-weight: 500; color: var(--ink-subtle); margin-top: 3px;
             white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rdr__rowend { text-align: right; flex: none; }
.rdr__dist { font-weight: 700; font-size: 14px; color: var(--ink); }
.rdr__dist.is-off { color: #4A463F; }
.rdr__dir { font-size: 11px; font-weight: 600; letter-spacing: .1em; color: var(--ink-tertiary); margin-top: 3px; }

.rdr__foot { padding: 18px 26px; font-size: 13px; line-height: 1.55; color: var(--ink-subtle); }
.rdr__am { color: var(--accent-ink); font-weight: 700; }
.rdr__cr { color: var(--ink); font-weight: 600; }

/* — permission / error states, in the same ground — */
.near { background: var(--e1-bg); }
.near--empty { text-align: center; padding: 40px 20px 34px; font-family: var(--ui); }
.near__h { margin: 0 0 6px; font-size: 18px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); }
.near__p { margin: 0 0 18px; font-size: 13px; color: var(--ink-subtle); line-height: 1.55; }
.near--empty.is-asking .near__h::after {
  content: ''; display: inline-block; width: 1em; text-align: start;
  animation: dots 1.4s steps(4, end) infinite;
}
@keyframes dots { 0% { content: ''; } 25% { content: '.'; } 50% { content: '..'; } 75% { content: '...'; } }

@media (prefers-reduced-motion: reduce) {
  .rdr__sweep, .rdr__beam { display: none; }
}

/* — in the Map preview slot, beside Details —
   The same radar at the slot's size rather than its own full-width one: a
   slimmer header, the disc beside the list, and the list scrolling inside the
   card instead of growing it. Sized by the CARD (a container query), not the
   viewport, because the slot is half a row on a desktop and a whole row on a
   phone. Below 520px of card the list goes under the disc. */
.dcard--radar { padding: 0; overflow: hidden; container-type: inline-size; display: flex; }
.dcard--radar > .rdr, .dcard--radar > .near { flex: 1; }

/* — the Delivery Route Map, in the Details card's slot —
   route-map.css draws it; the card only gives it a height (the design needs
   one) and gets out of the way. The radar beside it stretches to match. */
.dcard--route { padding: 0; overflow: hidden; height: 600px; display: flex; }
.route-host, .route-host > .mp { flex: 1; min-width: 0; height: 100%; }
.dcard--route .mp { border-radius: 0; min-height: 0; }
.dcard--radar .rdr__top { padding: 12px 18px; gap: 12px; }
.dcard--radar .rdr__brand { gap: 12px; }
.dcard--radar .rdr__mark { height: 24px; }
.dcard--radar .rdr__rule { height: 22px; }
.dcard--radar .rdr__title { font-size: 16px; }
.dcard--radar .rdr__meta { gap: 8px; }
.dcard--radar .rdr__k { font-size: 10px; }
.dcard--radar .rdr__origin { font-size: 12px; padding: 4px 9px; }
.dcard--radar .rdr__live { font-size: 10px; padding: 5px 9px; gap: 6px; }
.dcard--radar .rdr__livedot { width: 6px; height: 6px; }
.dcard--radar .rdr__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); min-height: 0; }
.dcard--radar .rdr__side { border-top: 0; border-left: 2px solid var(--wash-strong); min-height: 0; }
.dcard--radar .rdr__stage { min-height: 0; padding: 30px 26px; }
.dcard--radar .rdr__bloom { width: 420px; height: 420px; }
.dcard--radar .rdr__mesh { background-size: 24px 24px; }
.dcard--radar .rdr__scope { width: min(200px, 100%); }
.dcard--radar .rdr__disc { box-shadow: inset 0 0 40px rgba(0,0,0,.9), 0 0 0 2px var(--accent-wash); }
.dcard--radar .rdr__bearing { font-size: 10px; }
.dcard--radar .rdr__selfdot { width: 12px; height: 12px; }
.dcard--radar .rdr__self, .dcard--radar .rdr__selfpulse { width: 30px; height: 30px; }
.dcard--radar .rdr__pinring, .dcard--radar .rdr__pinping { width: 16px; height: 16px; }
.dcard--radar .rdr__scale, .dcard--radar .rdr__foot { display: none; }
.dcard--radar .rdr__count { padding: 14px 18px 10px; }
.dcard--radar .rdr__countrow { margin-top: 4px; gap: 8px; }
.dcard--radar .rdr__big { font-size: 32px; }
.dcard--radar .rdr__of { font-size: 13px; }
/* The list scrolls inside the card: the card is as tall as Details, not as
   long as the rep's book. */
.dcard--radar .rdr__list { flex: 1 1 0; min-height: 0; overflow-y: auto; }
.dcard--radar .rdr__list + .rdr__hr { display: none; }
.dcard--radar .rdr__row { padding: 10px 18px; gap: 12px; }
.dcard--radar .rdr__bullet { width: 10px; height: 10px; }
.dcard--radar .rdr__name { font-size: 14px; }
.dcard--radar .rdr__city { font-size: 11.5px; margin-top: 2px; }
.dcard--radar .rdr__dist { font-size: 13px; }
.dcard--radar .rdr__dir { font-size: 10.5px; margin-top: 2px; }
@container (max-width: 520px) {
  .dcard--radar .rdr__grid { grid-template-columns: minmax(0, 1fr); }
  .dcard--radar .rdr__side { border-left: 0; border-top: 2px solid var(--wash-strong); }
  .dcard--radar .rdr__list { max-height: 210px; flex: none; }
}



/* ── Unread badge on the rail ─────────────────────────────────────────────────
   The nav item is a flex column of icon + label on a phone, so the badge is
   positioned rather than placed in flow — it must not push the label off
   centre or change the item's height. */
.navitem { position: relative; }
.navitem__badge {
  position: absolute; top: 2px; left: 50%; margin-left: 6px;
  display: grid; place-items: center;
  min-width: 17px; height: 17px; padding: 0 4px; border-radius: 999px;
  background: var(--vivid); color: var(--on-accent);   /* dark on amber: white was 1.7:1 */
  font-size: 10px; font-weight: 800; font-style: normal; font-family: var(--mono);
  border: 2px solid var(--brown);   /* separates it from the icon behind */
  pointer-events: none;
}
.navitem__badge[hidden] { display: none; }

/* ── Toast / notification ─────────────────────────────────────────────────────
   Above the bottom bar on a phone, clear of the home indicator. */
.toast {
  position: fixed; z-index: 60;
  left: 50%; transform: translateX(-50%);
  /* Clear of the bottom bar and the home indicator. --safe-b is already
     env(safe-area-inset-bottom), so it is not added twice. */
  bottom: calc(72px + var(--safe-b) + 14px);
  display: flex; align-items: center; gap: 12px;
  /* max-content: centred by left:50%, a fixed box shrinks to fit HALF the
     screen, so a long message wrapped into a ~120px column on a phone
     (v4.133.1). Its own width, capped below, keeps it the full width. */
  width: max-content;
  max-width: min(520px, calc(100vw - 32px));
  padding: 11px 14px; border-radius: 12px;
  background: var(--e1-bg); border: 1px solid var(--line);
  box-shadow: 0 10px 30px var(--shadow-color);
  color: var(--white); font-size: 13.5px; line-height: 1.45;
}
.toast[hidden] { display: none; }
.toast.is-alert { border-color: var(--accent-ink); }
.toast__go {
  flex-shrink: 0; border: 0; border-radius: 8px; padding: 6px 12px;
  background: var(--amber); color: #231A0C;
  font: inherit; font-size: 12.5px; font-weight: 800; cursor: pointer;
}
.toast__go[hidden] { display: none; }

/* 1024px is where the rail stops being a bottom bar and becomes a side rail —
   the same breakpoint the shell uses. Below it the toast must stay above the
   bar; at and above it there is no bar to clear. */
@media (min-width: 1024px) {
  .toast { left: auto; right: 24px; bottom: calc(var(--safe-b) + 24px); transform: none; }
}
.muted { color: var(--steel); font-size: 13.5px; }

/* `.hero` was the single big number on the old home screen. The metric row
   replaced it with three, so nothing renders it any more. */
.greet { font-size: clamp(22px, 6vw, 30px); line-height: 1.18; margin-bottom: 18px; }
.greet em { font-style: italic; color: var(--accent-ink); font-weight: 700; }

.meter { height: 9px; border-radius: 99px; background: rgba(143,154,163,.24); overflow: hidden; margin-bottom: 16px; }
.meter > i { display: block; height: 100%; background: var(--amber); border-radius: 99px; transition: width .4s ease; }

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--tap); width: 100%;
  padding: 0 20px; border-radius: 99px;
  font-size: 15.5px; font-weight: 800; cursor: pointer;
  border: 2px solid transparent; text-decoration: none;
}
.btn--primary {                      /* "Get a Quote" — the mandated gradient */
  background: linear-gradient(180deg, var(--grad-top) 0%, var(--grad-bot) 100%);
  color: var(--on-accent);           /* 5.75:1, not 2.73:1 */
  border-color: var(--grad-bot);
}
.btn--primary:active { filter: brightness(.94); transform: scale(.985); }
.btn--outline {                      /* "View Products" — brown fill, orange outline + text */
  background: var(--brown); color: var(--accent-ink); border-color: var(--accent-ink);
}
.btn--outline:hover { background: #33271C; }
.btn--ghost { background: transparent; color: var(--steel); border-color: var(--line); }
.btn--sm { min-height: 38px; width: auto; font-size: 13px; padding: 0 14px; }
/* Destructive. Outlined rather than filled: it sits at the foot of a thread the
   rep is reading, and a solid red block there reads as an alert about the
   message rather than an action on it. #FF6B6B is 5.6:1 on the charcoal panel. */
.btn--danger {
  background: transparent; color: #FF6B6B;
  border: 1px solid rgba(255,107,107,.45);
}
.btn--danger:hover  { background: rgba(255,107,107,.12); border-color: #FF6B6B; }
.btn--danger:active { filter: brightness(.94); transform: scale(.985); }


/* ── Stats ────────────────────────────────────────────────────────────────── */
.grid { display: grid; gap: 12px; grid-template-columns: repeat(2, 1fr); }
.grid > * { min-width: 0; }
.stat__v { font-size: 27px; font-weight: 800; color: var(--accent-ink); font-family: var(--mono); }
.stat__v small { font-size: 13px; color: var(--steel); font-family: var(--ui); }

/* ── Metric row: three micro-cards, always one line ───────────────────────── */
/* Three across even on a 320px screen. `minmax(0,1fr)` rather than `1fr` —
   without the zero minimum a long number forces the track wider than its share
   and the third card is pushed off the edge. */
.metrics { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 9px; }
.metric {
  background: var(--brown); border: 1px solid var(--line);
  border-radius: 14px; padding: 12px 10px; min-width: 0; text-align: center;
}
.metric__k {
  margin: 0 0 6px; font-size: 9.5px; font-weight: 700; line-height: 1.3;
  letter-spacing: .05em; text-transform: uppercase; color: var(--steel);
}
.metric__v {
  margin: 0; font-size: clamp(17px, 5.4vw, 22px); line-height: 1.05;
  font-weight: 800; font-family: var(--mono); color: var(--accent-ink);
  overflow: hidden; text-overflow: ellipsis;
}
.metric__v small { font-size: 10.5px; font-weight: 600; color: var(--steel); font-family: var(--ui); }

/* ── Activity list ────────────────────────────────────────────────────────── */
.acts { display: flex; flex-direction: column; gap: 9px; }
.act {
  /* minmax(0,1fr): client names run long and some are Arabic, which does not
     break where a Latin name would. A plain 1fr track would widen the card
     rather than let the name ellipsise. */
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px; align-items: center;
  background: var(--brown); border: 1px solid var(--line);
  border-radius: 13px; padding: 12px 14px;
}
.act > * { min-width: 0; }
.act__c { font-size: 14px; font-weight: 700; min-width: 0;
          overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.act__v { font-size: 14px; font-weight: 800; font-family: var(--mono); color: var(--white);
          text-align: end; white-space: nowrap; }
.act__m { font-size: 11.5px; color: var(--steel); }
.act__s { justify-self: end; }

/* Status carries an icon and a word, never colour alone — about one man in
   twelve cannot separate the amber from the green. */
.pill {
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  font-size: 10px; font-weight: 800; letter-spacing: .04em;
  padding: 4px 9px; border-radius: 99px; border: 1px solid transparent;
}
.pill svg { width: 11px; height: 11px; fill: none; stroke: currentColor;
            stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
/* ── Proposal status, one colour each, on every badge in the app ─────────────
   Approved green, Rejected red, Awaiting decision amber — the activity pill,
   the account tag, the Orders chip and the breakdown pill all draw from this
   one block. They used to disagree: Approved was green in two places and amber
   in two others. The shapes still differ per screen; the colours do not. */
/* Two-class selectors: each family's base rule (.tag sets a grey background,
   declared further down) has one class and came later, so with one class here
   it won and every account tag was grey. */
.pill.pill--approved, .tag.tag--approved, .lo-chip.lo-chip--approved, .sp-pill.sp-pill--approved {
  background: var(--success-wash); color: var(--success);
  border-color: color-mix(in srgb, var(--success) 40%, transparent);
}
.pill.pill--rejected, .tag.tag--rejected, .lo-chip.lo-chip--rejected, .sp-pill.sp-pill--rejected {
  background: var(--danger-wash); color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 40%, transparent);
}
.pill.pill--awaiting, .tag.tag--awaiting, .lo-chip.lo-chip--awaiting, .sp-pill.sp-pill--awaiting {
  background: var(--accent-wash); color: var(--accent-ink);
  border-color: color-mix(in srgb, var(--accent) 44%, transparent);
}

/* ── Form fields ──────────────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: 7px; margin-bottom: 15px; }
.label { font-size: 13px; font-weight: 700; color: var(--white); }
.input-wrap { position: relative; display: flex; }

.input {
  width: 100%; min-height: var(--tap); padding: 0 15px;
  background: var(--brown);                  /* #2B2118 */
  color: var(--white);
  border: 1.5px solid var(--steel);          /* #8F9AA3 default */
  border-radius: 13px;
  font: 16px var(--ui);                      /* 16px or iOS zooms on focus */
  transition: border-color .16s ease, box-shadow .16s ease;
}
.input::placeholder { color: var(--steel); opacity: 1; }
.input:focus {
  outline: 0;
  border-color: var(--accent-ink);                /* #F7A11A on focus */
  box-shadow: 0 0 0 3px rgba(247,161,26,.18);
}
.input--select { padding-inline-end: 44px; appearance: none; -webkit-appearance: none; cursor: pointer; }
.input--select option { background: var(--brown); color: var(--white); }
.input.is-bad { border-color: #FF6B6B; }

.chev {
  position: absolute; inset-inline-end: 15px; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; pointer-events: none;
  fill: none; stroke: var(--steel); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
/* The unit suffix follows the manager's L/kg setting, so the field always says
   what the number will be read as. */
.input-unit {
  position: absolute; inset-inline-end: 15px; top: 50%; transform: translateY(-50%);
  color: var(--accent-ink); font-size: 13.5px; font-weight: 800; pointer-events: none;
}
.input-wrap .input[inputmode="decimal"] { padding-inline-end: 52px; }

.input--area { min-height: 104px; padding: 13px 15px; line-height: 1.5; resize: vertical; }

.err { margin: 0; font-size: 12.5px; color: #FF6B6B; }
.err:empty { display: none; }

/* Who this is going to. A request that silently routes somewhere is a request
   the rep cannot trust. */
.reqto {
  margin: 0 0 18px; padding: 11px 13px; border-radius: 11px;
  background: rgba(247,161,26,.1); border: 1px solid rgba(247,161,26,.34);
  font-size: 12.5px; line-height: 1.5; color: var(--steel);
}
.reqto b { color: var(--accent-ink); font-weight: 800; }

/* WhatsApp keeps its own green — a brand mark people recognise instantly is
   worth more here than palette consistency, and it reads as an escape hatch
   rather than another in-app action. */
.btn--wa {
  background: transparent; color: #4FD17A;
  border-color: rgba(79,209,122,.5); text-decoration: none;
}
.btn--wa:hover { background: rgba(79,209,122,.1); border-color: #4FD17A; }
/* The mark is a FILLED glyph. The generic `.btn svg` rule strokes its icons,
   which turned this into a hollow outline that read as a speech bubble. */
.ico-wa { width: 17px; height: 17px; fill: currentColor; stroke: none; }

/* ── Unit toggle (local to one quote) ─────────────────────────────────────── */
.qty-head { display: flex; align-items: center; gap: 12px; }
.qty-head .label { flex: 1; }

.useg {
  position: relative; display: inline-grid; grid-auto-flow: column;
  grid-auto-columns: 1fr;
  background: var(--brown); border: 1px solid var(--steel);
  border-radius: 99px; padding: 3px;
}
.useg__btn {
  position: relative; z-index: 2;
  min-width: 46px; min-height: 32px; padding: 0 12px;
  border: 0; background: none; border-radius: 99px; cursor: pointer;
  color: var(--steel); font-size: 12.5px; font-weight: 800;
  transition: color .2s ease;
}
.useg__btn.is-on { color: var(--on-accent); }      /* charcoal on amber: 7.53:1 */
.useg__glider {
  position: absolute; z-index: 1; top: 3px; bottom: 3px;
  inset-inline-start: 3px; width: calc(50% - 3px);
  background: var(--amber); border-radius: 99px;
  transform: translate3d(0,0,0); will-change: transform;
  transition: transform .24s cubic-bezier(.4,0,.2,1);
}
.useg[data-on="kg"] .useg__glider { transform: translate3d(100%, 0, 0); }

/* The same quantity in the other unit, so the rep can sanity-check against a
   drum label or a weighbridge ticket without doing the sum. */
.conv { margin: 0; font-size: 12px; color: var(--steel); font-family: var(--mono); }

/* ── Live price breakdown ─────────────────────────────────────────────────── */
.calc {
  background: var(--brown); border: 1px solid var(--line);
  border-radius: 14px; padding: 14px 16px; margin-bottom: 16px;
}
.calc__row {
  display: flex; align-items: baseline; gap: 12px;
  padding: 8px 0; border-bottom: 1px solid var(--line-soft);
}
.calc__k { flex: 1; font-size: 12.5px; color: var(--steel); }
.calc__v {
  font-size: 14px; font-weight: 700; font-family: var(--mono);
  font-variant-numeric: tabular-nums; color: var(--white);
}
.calc__row--total { border-bottom: 0; padding: 14px 0 2px; align-items: center; }
.calc__row--total .calc__k { font-size: 13px; font-weight: 700; color: var(--white); }
/* The number the rep says out loud. Everything else on this card is smaller
   and quieter so this is what the eye lands on. */
.calc__total {
  font-size: clamp(26px, 8vw, 34px); line-height: 1; font-weight: 800;
  font-family: var(--mono); color: var(--accent-ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.calc__note { margin: 10px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--steel); }
.calc__note b { color: var(--accent-ink); font-family: var(--mono); }

.qhead { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; }
.qhead .iconbtn { margin-inline-start: auto; width: 40px; height: 40px; }
.sheet__title { font-size: 20px; font-weight: 800; }
/* `.qtotal` was the single-line running total. The live breakdown block
   (`.calc`) replaced it with base / tier / total. */

/* The form sheet must clear the on-screen keyboard. dvh shrinks when the
   keyboard opens; vh does not, which is what buries the submit button. */
.sheet--form .sheet__body { max-height: 92dvh; }
.sheet--form .btn { margin-top: 10px; }

/* ── Search & chips ───────────────────────────────────────────────────────── */
/* Theme tokens. It was a fixed charcoal with white text, which is right in the
   dark theme and a black slab across the top of every light-mode screen. */
.search {
  width: 100%; min-height: var(--tap);
  background: var(--e2-bg); border: 1px solid var(--hairline-strong);
  border-radius: 12px; padding: 0 16px; color: var(--ink);
}
.search::placeholder { color: var(--steel); }
.search:focus { outline: 0; border-color: var(--accent-ink); }

.chips {
  display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px;
  scrollbar-width: none;
  /* Belt and braces: even if this ever stops being a direct child of .content,
     it must not be allowed to collapse. */
  flex: 0 0 auto; min-height: 42px; align-items: center;
}
.chips::-webkit-scrollbar { display: none; }
.chip {
  flex: 0 0 auto; min-height: 36px; padding: 0 14px; border-radius: 99px;
  background: var(--e1-bg); border: 1px solid var(--line);
  color: var(--steel); font-size: 13px; font-weight: 700; cursor: pointer;
}
.chip.is-on { background: var(--amber); color: var(--on-accent); border-color: var(--accent-ink); }

/* Search and Add on one line. The button is flex: none so a long placeholder
   can never squeeze it off the row — the only way to create an account. */
.acct-bar { display: flex; gap: 10px; align-items: stretch; min-width: 0; }
.acct-bar .search { flex: 1 1 auto; min-width: 0; }
.acct-add { flex: none; width: auto; padding: 0 20px; min-height: var(--tap); }

/* A row shows its proposal status when it has one, because that is the field
   the dashboard chart is built from — otherwise it falls back to the stage. */
.tag--ps { border: 1px solid transparent; }
/* Colours: the shared proposal-status block, with .pill--approved. */

/* ── Proposal status + value, on the account sheet ────────────────────────────
   Set apart from the read-only <dl> above it because these two fields are the
   rep's to change, and they are what "Proposals by status" is built from. */
.pset {
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 10px;
}
.pset__h { margin: 0; font-size: 13px; font-weight: 800; color: var(--white); }
.pset__seg { display: flex; flex-wrap: wrap; gap: 8px; }
.pset__opt {
  /* Wraps rather than scrolls: four options is a set to read at a glance, and a
     horizontally scrolling strip hides the one that clears the field. */
  flex: 0 0 auto; min-height: var(--tap); padding: 0 14px; border-radius: 99px;
  background: var(--brown); border: 1.5px solid var(--steel);
  color: var(--white); font: 700 13px var(--ui); cursor: pointer;
}
.pset__opt:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
/* Charcoal on amber is 7.53:1; white on it is 2.1:1 and fails at this size. */
.pset__opt.is-on {
  background: var(--amber); border-color: var(--accent-ink); color: var(--on-accent);
}
.pset__hint { margin: 0; font-size: 11.5px; line-height: 1.5; color: var(--steel); }
.pset__link { border: 0; background: none; padding: 0; margin-inline-start: 6px; color: var(--accent-ink); font: inherit; font-weight: 700;
              text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
/* Why was it rejected? — a window over the account sheet */
.rj { position: fixed; inset: 0; z-index: 9500; display: grid; place-items: center; padding: 16px; background: rgba(0,0,0,.55); }
.rj__card { width: min(100%, 460px); max-height: calc(100dvh - 32px); overflow-y: auto; padding: 20px; border-radius: 18px;
            background: var(--e3-bg); border: 1px solid var(--e3-border); color: var(--white); box-shadow: var(--shadow-3); }
.rj__t { margin: 2px 0 4px; font-size: 20px; font-weight: 800; color: var(--white); }
.rj__sub { margin: 0 0 14px; font-size: 13px; color: var(--steel); }
.rj__chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.rj__chips .chip { min-height: 40px; }
.rj__acts { display: flex; gap: 10px; justify-content: flex-end; margin-top: 12px; flex-wrap: wrap; }
.rj__acts .btn { width: auto; min-width: 120px; }
/* Notes from the manager on a deal (account sheet, Need help sheet). */
.mnotes { display: flex; flex-direction: column; gap: 8px; margin: 2px 0 4px; }
.mnote { margin: 0; padding: 10px 12px; border-radius: 10px; border-inline-start: 3px solid var(--amber, #F5A524);
         background: var(--wash, rgba(255,255,255,.05)); font-size: 13px; line-height: 1.5; color: var(--white); overflow-wrap: anywhere; }
.mnote .muted { font-size: 11.5px; }

/* ── List rows ────────────────────────────────────────────────────────────── */
.rows { display: flex; flex-direction: column; gap: 10px; }
.row {
  /* minmax(0,1fr), not 1fr — see .row > span below. The plain 1fr track refuses
     to shrink under its content, which is what pushed the card past its edge. */
  display: grid; grid-template-columns: 42px minmax(0, 1fr) auto;
  gap: 12px; align-items: center;
  width: 100%; text-align: start; min-width: 0;
  /* Product rows, catalogue results, equivalents: the same card treatment as
     everything else, so a list reads as a stack of objects rather than as
     ruled lines. This is the most-scrolled surface in the app. */
  background: var(--e1-bg); border: 1px solid var(--e1-border);
  border-radius: var(--r-lg); padding: 13px 14px; cursor: pointer;
  box-shadow: var(--shadow-1);
  transition: transform var(--dur-fast) var(--ease),
              box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              background var(--dur) var(--ease);
}
.row:hover {
  background: var(--e2-bg);
  border-color: var(--hairline-strong);
  box-shadow: var(--shadow-2);
  transform: translateY(var(--lift));
}
.row:active { transform: translateY(0) scale(var(--press)); box-shadow: var(--shadow-1); }
/* The product initial, sized like the reference's merchant logos: a soft
   rounded square, accent-washed, not a hard chip. */
.row__ini {
  width: 42px; height: 42px; border-radius: var(--r-md); display: grid; place-items: center;
  background: var(--accent-wash); color: var(--accent-ink); font-weight: 700; font-size: 13px;
}
/* A grid or flex item will not shrink below its content by default, so a long
   grade list ("ISO VG 10 15 22 32 37 46 68") forced this cell wider than its
   track and spilled out of the card. min-width:0 is what lets it shrink — and
   it is also what makes the ellipsis below actually fire. */
.row > span { min-width: 0; }

/* These are <span>s, so they were laid out inline and ran together on one line:
   the product name and its grade list read as a single run of text. `display:
   block` is also required for text-overflow to apply at all. */
/* The whole name and the whole grade list, wrapped (v4.240, the layout audit: at 390 px a product read
   "Petromix HLP Hydraul…" and its grades stopped mid-list). */
.row__t {
  display: block; font-size: 14.5px; font-weight: 700; line-height: 1.3;
  overflow-wrap: anywhere;
}
.row__s {
  display: block; font-size: 12.5px; color: var(--steel); margin-top: 2px; line-height: 1.4;
  overflow-wrap: anywhere;
}

.tag {
  font-size: 10.5px; font-weight: 800; letter-spacing: .05em;
  padding: 4px 9px; border-radius: 99px;
  background: rgba(143,154,163,.18); color: var(--steel);
}
.tag--won  { background: rgba(247,161,26,.18); color: var(--accent-ink); }
.tag--lost { background: rgba(143,154,163,.14); color: var(--steel); }
.tag--open { background: rgba(244,123,11,.18); color: #FFB067; }

/* The team bars and the all-accounts table lived here when this file also had
   to serve managers. They have their own dashboard now, and the rep app
   rendered neither one. */

/* ── Detail sheet ─────────────────────────────────────────────────────────── */
.sheet { position: fixed; inset: 0; z-index: 60; display: none; }
.sheet.is-open { display: block; }
/* The scrim blurs as well as dims. This is the second and last place
   backdrop-filter is allowed: a full-screen overlay that exists for a few
   seconds while the sheet is open, not a per-card effect on a scrolling list.
   It is what makes the sheet read as being in FRONT of the app rather than
   pasted on top of it. */
.sheet__scrim {
  position: absolute; inset: 0;
  background: rgba(0,0,0,.55);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
/* ══ THE PRODUCT CARD ════════════════════════════════════════════════════════
   This sheet IS the product card: it is what a rep holds up in front of a
   customer, so it gets the top of the elevation ladder and the largest radius
   in the system. No hairline border; at level 3 the fill and the shadow do the
   separating, which is the reference's whole approach to depth. */
.sheet__body {
  position: absolute; inset-inline: 0; bottom: 0; max-height: 88%;
  overflow-y: auto;
  background: var(--e3-bg);
  border-radius: var(--r-2xl) var(--r-2xl) 0 0;
  border: 1px solid var(--e3-border); border-bottom: 0;
  box-shadow: var(--shadow-3);
  padding: 20px 18px calc(var(--safe-b) + 24px);
}
/* The drag grip is a SHAPE, not text. --steel bridges to muted ink, which
   would leave it invisible on a light sheet. */
.sheet__grip { width: 40px; height: 4px; border-radius: var(--r-pill);
               background: var(--ink-tertiary);
               opacity: .5; margin: 0 auto 16px; }
/* ══ SPEC ROWS ═══════════════════════════════════════════════════════════════
   Was a bare two-column grid: label, value, label, value, down the sheet. The
   design skill calls a long flat spec list the laziest available layout, and
   the reference answers it by giving every row its own rounded container.

   Each dt/dd pair now reads as one banded row. There is no wrapper element
   around a pair in a <dl>, so the band is built from two halves that meet:
   the dt carries the leading corners, the dd the trailing ones, and the row
   gap is zero while the column gap between pairs is 4px.

   Logical radius properties (`border-start-start-radius`) rather than the
   physical shorthand, so the band flips correctly in Arabic instead of
   rounding the wrong end. */
.kv {
  display: grid; grid-template-columns: 116px minmax(0, 1fr);
  gap: 4px 0; font-size: 13.5px; margin-top: 14px;
}
.kv dt, .kv dd {
  background: var(--wash);
  padding: 10px 12px;
  min-width: 0;
  display: flex; align-items: center;
}
.kv dt {
  color: var(--ink-subtle); font-weight: 500;
  border-start-start-radius: var(--r-sm);
  border-end-start-radius: var(--r-sm);
}
/* Values here are descriptions, grade lists and approval strings — long,
   unbroken and often without spaces. `anywhere` lets them wrap rather than
   widen the sheet. */
.kv dd {
  margin: 0; overflow-wrap: anywhere; color: var(--ink);
  border-start-end-radius: var(--r-sm);
  border-end-end-radius: var(--r-sm);
}
/* A very narrow sheet stacks the pair; the halves then need all four corners
   or the band looks broken at the join. */
@media (max-width: 380px) {
  .kv { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
  .kv dt { border-radius: var(--r-sm) var(--r-sm) 0 0; padding-bottom: 4px; }
  .kv dd { border-radius: 0 0 var(--r-sm) var(--r-sm); padding-top: 4px; margin-bottom: 4px; }
}

.empty { text-align: center; padding: 34px 16px; color: var(--steel); font-size: 13.5px; }
/* The bold first words are the empty state's heading. Inline, they ran into
   the sentence after them: "No requests yetAnything you send…". */
.empty > b:first-child { display: block; margin-bottom: 4px; color: var(--ink); font-size: 14.5px; }

/* The role-switch rules lived here when this file served both audiences.
   Managers have their own dashboard; this is the rep app and has no second
   role to switch into. */

/* ── DESKTOP ≥1024px: bottom bar becomes a side rail ──────────────────────── */
@media (min-width: 1024px) {
  .app {
    grid-template-columns: var(--rail-w) 1fr;
    grid-template-rows: auto 1fr;
    grid-template-areas: "rail topbar" "rail content";
  }
  .rail {
    border-top: 0; border-inline-end: 1px solid var(--line);
    padding: 24px 14px calc(var(--safe-b) + 20px); gap: 22px;
  }
  /* Was a typed "PETROMIX FIELD" in Archivo. It is the real lockup now, with
     FIELD as a caption under it — the lockup says Petromix Middle East, and
     this app is Petromix Field, so the caption still has a job. */
  .rail .rail__brand { display: block; padding: 0 10px; }
  .rail__brand .pmx-logo { width: min(190px, 100%); }
  .rail__brand span {
    display: block; font-size: 9.5px; font-weight: 900; letter-spacing: .24em;
    color: var(--accent-ink); margin-top: 6px;
  }
  /* Matching specificity to the mobile hide rule above, which is now
     .rail-prefixed; without the prefix these would lose and the desktop
     sidebar would come up with no brand, no CTA and no footer. */
  .rail .rail__cta  { display: inline-flex; margin-top: auto; }
  .rail .rail__foot { display: block; font-size: 11px; color: var(--steel); padding: 10px 10px 0; }
  .rail__nav  { flex-direction: column; gap: 4px; }
  .navitem {
    flex: 0 0 auto; flex-direction: row; justify-content: flex-start;
    gap: 12px; padding: 12px 14px; border-radius: 11px; font-size: 14.5px; text-align: start;
  }
  .navitem:hover    { background: var(--wash); }
  .navitem.is-active{ background: rgba(247,161,26,.14); }
  /* The item is a row here, so the badge sits at its end in normal flow rather
     than pinned over the icon. */
  .navitem__badge {
    position: static; margin-left: auto; border: 0;
    min-width: 20px; height: 20px; font-size: 11px;
  }

  .content { padding: 24px 32px 40px; gap: 18px; }
  .grid    { grid-template-columns: repeat(4, 1fr); gap: 16px; }
  /* Same reason as the row's own tracks: a plain 1fr column will not shrink
     below its widest child, so one long product name widens both columns and
     the pair overflows the page. */
  .rows    { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .sheet__body {
    inset: 50% auto auto 50%; transform: translate(-50%, -50%);
    max-width: 620px; max-height: 84%; border-radius: 18px; border: 1px solid var(--line);
  }
}
@media (min-width: 1600px) {
  .content > * { max-width: 1400px; width: 100%; margin-inline: auto; }
}

/* ── Accessibility states ─────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  body { animation: none; }             /* the ambient wave is motion too */
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}
@media (prefers-contrast: more) {
  :root { --steel: #B7C1C9; --line: rgba(183,193,201,.45); --panel: rgba(35,35,35,.97); }
  .panel, .btn, .row { border-width: 2px; }
}
@media (prefers-reduced-transparency: reduce) {
  :root { --panel: #232323; }
  .topbar, .rail { backdrop-filter: none; -webkit-backdrop-filter: none;
                   background: var(--brown); }
  .panel { backdrop-filter: none; -webkit-backdrop-filter: none; }
}
:where(button, a, input, select, [tabindex]):focus-visible {
  outline: 3px solid var(--amber); outline-offset: 2px; border-radius: 8px;
}



/* ══ LIVE ORDERS ════════════════════════════════════════════════════════════
   The supplied dashboard's LAYOUT, in the app's palette.

   The design came as a light screen — #F4F7FB ground, white cards, lime and
   a second orange. Every one of those is now an app token: charcoal panels
   over the body's ambient gradient, amber where the lime was, vivid where the
   second orange was, steel for muted text. No new colour is introduced.

   Geometry is untouched: 190px sidebar, 368px right column, 14px gutters,
   139px KPI cards — all measured off the image.

   Two substitutions worth naming:
   · Lime on white became amber on charcoal, so the fills carry CHARCOAL ink
     per the rule at the top of this file. White on amber is 2.1:1.
   · The pink "down" badge became steel, which is what this app already uses
     for a negative state (.tag--lost). It has no red, and inventing one for
     four KPI cards is not a good enough reason to break a fixed palette.
   ═════════════════════════════════════════════════════════════════════════ */
/* The app's rail and header STAY on this screen. They used to be hidden here
   because Live Orders brought its own sidebar; that sidebar is gone — the six
   sections are picked from a sub-menu in the rail itself — so hiding the rail
   would leave no way to reach them. */
/* No background here: the body's ambient gradient shows through, exactly as it
   does behind every other screen. */
.on-orders .content { padding: 0; gap: 0; }

.lo { min-height: 100%; color: var(--white); font-family: var(--ui); }

/* ── main column ── */
.lo__main { padding: 22px; min-width: 0; display: flex; flex-direction: column; gap: 16px; }

.lo-head { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.lo-head__who { flex: 1 1 260px; min-width: 0; }
.lo-head__who h1 {
  margin: 0; font-size: clamp(22px, 2.6vw, 33px); font-weight: 800;
  letter-spacing: -.02em; line-height: 1.15;
}
.lo-head__who p { margin: 5px 0 0; font-size: 13px; color: var(--steel); }
.lo-head__acts { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.lo-pill {
  display: inline-flex; align-items: center; gap: 7px; min-height: 40px;
  padding: 0 15px; border-radius: 99px; background: var(--panel);
  border: 1px solid var(--line); font: 600 12.5px var(--ui);
  color: var(--white); white-space: nowrap;
}
.lo-pill svg {
  width: 15px; height: 15px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.lo-pill--btn { cursor: pointer; }
.lo-pill--btn:hover { background: var(--wash); border-color: var(--accent-ink); }
.lo-round {
  width: 40px; height: 40px; flex: none; border-radius: 50%; border: 0;
  background: var(--amber); color: var(--on-accent); cursor: pointer;
  display: grid; place-items: center;
}
.lo-round svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round;
}
.lo-round:hover { background: var(--vivid); }
.lo-pill--btn:focus-visible, .lo-round:focus-visible { outline: 2px solid var(--white); outline-offset: 2px; }

/* The refresh confirmation is the full-screen mark — .pmx-flash, defined once
   in core.js and shared with the manager dashboard, so the two interfaces
   cannot drift. Nothing for it here. */

.lo__kpis { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; }

/* ── KPI cards ── */
.lo-kpi {
  position: relative;
  background: var(--e1-bg); border: 1px solid var(--e1-border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  padding: 18px; min-height: 139px;
  display: flex; flex-direction: column; gap: 9px; min-width: 0;
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.lo-kpi::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; z-index: 0; background: var(--sheen);
}
.lo-kpi > * { position: relative; z-index: 1; }
.lo-kpi:hover { transform: translateY(var(--lift)); box-shadow: var(--shadow-2);
                border-color: var(--hairline-strong); }
/* The lime hero card becomes the amber one. Everything inside it switches to
   charcoal ink, which is the rule at the top of this file. */
/* Was a SOLID AMBER SLAB, and the loudest object on a workspace screen where
   the data should be. It also competed with the Home hero for the one
   saturated moment the page is allowed.
   Same hierarchy now, a fraction of the volume: a step up the ladder behind an
   accent ring. */
.lo-kpi--hero {
  background: var(--e2-bg);
  border-color: var(--e2-border);
  box-shadow: var(--shadow-2), var(--glow-ring);
  color: var(--ink);
}
.lo-kpi--hero::before { background: var(--sheen-warm); }
.lo-kpi--hero:hover { box-shadow: var(--shadow-3), var(--glow-strong); }

.lo-kpi__top { display: flex; align-items: center; gap: 9px; min-width: 0; }
.lo-kpi__ico {
  width: 34px; height: 34px; flex: none; border-radius: var(--r-md); display: grid;
  place-items: center; background: var(--wash-strong); color: var(--ink);
}
.lo-kpi--hero .lo-kpi__ico { background: var(--accent-wash); color: var(--accent-ink); }
.lo-kpi__ico svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.lo-kpi h2 {
  margin: 0; font-size: 15px; font-weight: 700; min-width: 0;
  overflow-wrap: break-word;   /* v4.240 layout audit: wraps, never cut */
}
.lo-kpi__v {
  margin: 0; font-size: clamp(24px, 2.5vw, 33px); font-weight: 800;
  letter-spacing: -.03em; line-height: 1.05;
  overflow-wrap: anywhere;   /* a product name (Top product) wraps instead of being cut (v4.240) */
}
.lo-kpi__v small { font-size: .46em; font-weight: 700; color: var(--steel); margin-inline-start: 4px; }
.lo-kpi--hero .lo-kpi__v small { color: var(--ink-subtle); }
.lo-kpi__none { margin: 0; font-size: 15px; font-weight: 600; color: var(--steel); }
.lo-kpi--hero .lo-kpi__none { color: var(--ink-subtle); }
.lo-kpi__foot { margin: auto 0 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.lo-tag {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px 9px;
  border: 1px solid transparent; border-radius: 99px;
  font-size: 11.5px; font-weight: 700; white-space: nowrap;
}
.lo-tag svg {
  width: 12px; height: 12px; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
}
/* Up reuses the green this app already carries on .pill--approved and the sync
   badge. Down is steel, which is what .tag--lost uses — there is no red in the
   palette and a delta badge is not a reason to add one. Both carry an arrow as
   well as a colour. */
.lo-tag--up   { background: var(--success-wash);  color: var(--success);   border-color: var(--success-wash); }
.lo-tag--down { background: rgba(143,154,163,.15); color: var(--ink-muted);  border-color: rgba(143,154,163,.42); }
.lo-tag--flat { background: var(--wash-strong); color: var(--ink-muted); font-weight: 600; }
/* On the amber card those translucent fills have nothing to sit on, so the two
   states get solid charcoal instead and stay legible. */
.lo-kpi--hero .lo-tag { background: var(--wash-strong); border-color: var(--hairline-strong); color: var(--ink-subtle); }
.lo-kpi__vs { font-size: 11.5px; color: var(--steel); }
.lo-kpi--hero .lo-kpi__vs { color: var(--ink-subtle); }

/* ── shared card chrome ── */
/* Live Orders cards, same treatment. backdrop-filter removed for the same
   reason as everywhere else: a blur per card in a scrolling workspace is a
   continuous GPU cost, and the surface ladder separates them without it. */
.lo-card {
  position: relative;
  background: var(--e1-bg); border: 1px solid var(--e1-border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  padding: 18px; min-width: 0;
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.lo-card::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; z-index: 0; background: var(--sheen);
}
.lo-card > * { position: relative; z-index: 1; }
.lo-card:hover { box-shadow: var(--shadow-2); border-color: var(--hairline-strong); }

.lo-card__h { display: flex; flex-wrap: wrap; align-items: center; gap: 9px; margin-bottom: 14px; min-width: 0; }   /* the note drops below on a narrow card (v4.240) */
.lo-card__ico {
  width: 32px; height: 32px; flex: none; border-radius: var(--r-md); display: grid;
  place-items: center; background: var(--wash-strong); color: var(--ink);
}
.lo-card__ico svg {
  width: 17px; height: 17px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.lo-card__h h2 {
  margin: 0; font-size: 16px; font-weight: 800; flex: 1 1 auto; min-width: 0;
  overflow-wrap: break-word;   /* "Volume ti…" at 320 px: wraps now (v4.240) */
}
.lo-sel {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  padding: 7px 12px; border-radius: 99px; background: var(--wash);
  border: 1px solid var(--line); font-size: 12px; font-weight: 600;
  color: var(--steel); white-space: nowrap;
}
.lo-sel svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; }

/* ── donut ── */
.lo-act__body { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.lo-act__ring { position: relative; width: 150px; flex: none; }
.lo-act__ring svg { width: 100%; height: auto; display: block; }
.lo-act__pct {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 25px; font-weight: 800; letter-spacing: -.02em; pointer-events: none;
}
.lo-act__leg { list-style: none; margin: 0; padding: 0; flex: 1 1 150px; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.lo-act__leg li { display: grid; grid-template-columns: 9px minmax(0, 1fr); gap: 8px; align-items: baseline; }
.lo-act__dot { width: 9px; height: 9px; border-radius: 50%; }
.lo-act__leg b { font-size: 14.5px; font-weight: 800; letter-spacing: -.02em; }
.lo-act__leg small {
  grid-column: 2; font-size: 11px; color: var(--steel); display: block;
  overflow-wrap: anywhere;   /* v4.240: a long client name wraps, never cut */
}
.lo-act__none { margin: 0; font-size: 13px; color: var(--steel); line-height: 1.6; }

/* ── narrower than the design ────────────────────────────────────────────── */
@media (max-width: 1180px) {
  .lo-act__ring { width: 130px; }
}
@media (max-width: 860px) {
  .lo__main { padding: 16px; }
}
@media (max-width: 560px) {
  .lo__kpis { grid-template-columns: minmax(0, 1fr); }
  .lo-head__acts { width: 100%; }
}

/* ── Live Orders: the eight non-dashboard views ───────────────────────────── */
.lo-panel { display: flex; flex-direction: column; gap: 0; }
.lo-panel + .lo-panel { margin-top: 14px; }
/* A three-across KPI strip for the views that carry one. Same card, same
   height, one fewer column. */
.lo__kpis--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-bottom: 14px; }
@media (max-width: 760px) { .lo__kpis--3 { grid-template-columns: minmax(0, 1fr); } }

.lo-note { margin: 0 0 14px; font-size: 12.5px; line-height: 1.6; color: var(--steel); }
.lo-note b { color: var(--white); font-weight: 700; }
.lo-empty { margin: 0; font-size: 13px; line-height: 1.7; color: var(--steel); }
.lo-empty b { color: var(--white); }

/* The table scrolls inside its own box rather than widening the card — the
   same lesson as the chips row: a wide child must scroll, not push. */
.lo-tblwrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 -4px; }
/* It is focusable so it can be scrolled from the keyboard, so it needs a focus
   ring — a focusable element with no visible focus is worse than an
   unreachable one. */
.lo-tblwrap:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; border-radius: 8px; }
/* ══ ORDER TABLES ════════════════════════════════════════════════════════════
   A hairline under every single row is the pattern the design skill names as
   the worst default, and it is what made these tables read as a spreadsheet
   pasted into the app.

   Rows now separate by a zebra wash instead, the header keeps one real rule
   under it, and the whole row highlights on hover. Denser to read, and it
   matches how the reference lists transactions: banded blocks, no rules. */
.lo-tbl { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
.lo-tbl th, .lo-tbl td {
  padding: 11px 10px; text-align: start; white-space: nowrap;
  border-bottom: 0;
}
.lo-tbl thead th {
  border-bottom: 1px solid var(--hairline);
  color: var(--ink-subtle); font-weight: 500;
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
}
.lo-tbl tbody tr { transition: background var(--dur-fast) var(--ease); }
.lo-tbl tbody tr:nth-child(even) { background: var(--wash); }
.lo-tbl tbody tr:hover { background: var(--wash-strong); }
/* The band needs its ends rounded or it reads as a full-bleed stripe. */
.lo-tbl tbody td:first-child {
  border-start-start-radius: var(--r-xs); border-end-start-radius: var(--r-xs);
}
.lo-tbl tbody td:last-child {
  border-start-end-radius: var(--r-xs); border-end-end-radius: var(--r-xs);
}
.lo-tbl th {
  font-size: 10.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--steel); border-bottom-color: var(--line);
}
.lo-tbl td { color: var(--white); }
/* Figures right-aligned and tabular, so columns of numbers actually line up. */
.lo-tbl .is-num { text-align: end; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.lo-tbl tbody tr:last-child td { border-bottom: 0; }
.lo-tbl tbody tr:hover td { background: var(--wash); }
/* The first column is the one that may wrap: a company name is long and
   Arabic, the figures beside it are not. */
.lo-tbl td:first-child {
  white-space: normal; min-width: 140px; max-width: 260px; font-weight: 600;
}

.lo-chip {
  display: inline-block; padding: 3px 9px; border-radius: 99px;
  border: 1px solid transparent; font-size: 11px; font-weight: 700; white-space: nowrap;
}
/* Colours: the shared proposal-status block, with .pill--approved. */
/* Past a fortnight a row needs to stand out from the fifty above it. */
.lo-age { color: var(--accent-ink); font-weight: 800; }
.lo-owner { color: var(--steel); font-size: 12px; }

/* ── Live Orders: Back ─────────────────────────────────────────────────────── */
.lo-head__nav { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.lo-back {
  display: inline-flex; align-items: center; gap: 6px; min-height: 36px;
  padding: 0 13px 0 9px; border-radius: 99px;
  background: var(--wash); border: 1px solid var(--line);
  color: var(--white); font: 700 12.5px var(--ui); cursor: pointer;
  max-width: 100%; min-width: 0;
}
.lo-back svg {
  width: 15px; height: 15px; flex: none; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
}
.lo-back span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lo-back:hover { background: var(--wash-strong); border-color: var(--accent-ink); }
.lo-back:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
/* ══ BRAND ══════════════════════════════════════════════════════════════════
   One logo across the whole product: icons/logo.png, the Petromix Middle East
   lockup. auth.html and manager.html already used it; the rep app drew its own
   approximations instead — a typed "PETROMIX FIELD" wordmark in the rail, a
   conic-gradient circle in the Live Orders sidebar, and a hand-drawn P on the
   radar card. Three different marks for one brand.

   Those were drawn rather than loaded because an <img> looked like a network
   dependency in an offline-first app. It is not: logo.png sits in the service
   worker's precache list, so it is on the device with everything else.
   ═════════════════════════════════════════════════════════════════════════ */
.pmx-logo { width: 100%; height: auto; display: block; }

/* The P alone.

   The lockup is a single image, so the mark is a crop of it rather than a
   second file that could drift out of step. The artwork is 2933x444; the P
   occupies the leftmost ~595px, so a box of ratio 595/444 = 1.34 showing the
   image at full height, left-aligned, is exactly the mark and nothing else.
   Change the height and the crop follows — there is no second number to keep
   in sync. */
.pmx-mark {
  display: block; aspect-ratio: 1.34; overflow: hidden; flex: none;
}
.pmx-mark img {
  height: 100%; width: auto; max-width: none; display: block;
  object-fit: cover; object-position: left center;
}
/* Very old Safari has no aspect-ratio; the crop would collapse to zero width
   and the mark would vanish. A width tied to the same ratio is the fallback. */
@supports not (aspect-ratio: 1) {
  .pmx-mark { width: 1.34em; }
  .rdr__mark { width: 45.5px; }
}

/* The rail lockup in LIGHT mode.

   logo.png has a WHITE wordmark, so on the light rail only the amber P showed.
   invert() would rescue the wordmark and wreck the amber; a dark plate behind
   it (the manager page's stopgap) puts a black box in a white sidebar. Instead
   the image is split at the P: the P stays the real artwork, and everything to
   its right is redrawn in ink using logo.png ITSELF as a stencil — so the
   letterforms cannot drift from the real lockup, and no second file is needed.

   20.3% is where the P ends: the artwork is 2933px wide and the P occupies its
   first 595px, the same figure .pmx-mark crops on. Only the laptop rail shows
   the lockup — the phone's bottom bar hides the brand entirely. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .rail__brand { position: relative; }
  :root:not([data-theme="dark"]) .rail__brand .pmx-logo { clip-path: inset(0 79.7% 0 0); }
  :root:not([data-theme="dark"]) .rail__brand::before {
    content: ''; position: absolute; top: 0; left: 10px;
    width: min(190px, calc(100% - 20px)); aspect-ratio: 2933 / 444;
    background: var(--ink); pointer-events: none;
    -webkit-mask: url("./icons/logo.png") no-repeat 0 0 / 100% 100%;
            mask: url("./icons/logo.png") no-repeat 0 0 / 100% 100%;
    clip-path: inset(0 0 0 20.3%);
  }
}
:root[data-theme="light"] .rail__brand { position: relative; }
:root[data-theme="light"] .rail__brand .pmx-logo { clip-path: inset(0 79.7% 0 0); }
:root[data-theme="light"] .rail__brand::before {
  content: ''; position: absolute; top: 0; left: 10px;
  width: min(190px, calc(100% - 20px)); aspect-ratio: 2933 / 444;
  background: var(--ink); pointer-events: none;
  -webkit-mask: url("./icons/logo.png") no-repeat 0 0 / 100% 100%;
          mask: url("./icons/logo.png") no-repeat 0 0 / 100% 100%;
  clip-path: inset(0 0 0 20.3%);
}
:root[dir="rtl"] .rail__brand::before { left: auto; right: 10px; }

/* ══ SALES REPORT ═══════════════════════════════════════════════════════════
   The supplied dashboard's layout, in the app's palette. Proportions measured
   off the image: a flexible left column with a 2x2 stat grid over a bar chart,
   and a ~300px right column holding the rings over the bubbles.

   Not carried over: the "Upgrade Pro — $30" card. This app has no
   subscription, and drawing a paywall into a field-sales tool invents a product
   that does not exist.
   ═════════════════════════════════════════════════════════════════════════ */
.rp-date { margin: -6px 0 0; font-size: 13px; color: var(--steel); }

.rp-grid { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 14px; align-items: start; }
.rp-left, .rp-right { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.rp-stats { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; }
/* The activity card and the top-clients donut, side by side under the bar
   chart. Each needs about 320px, so below two of those widths they stack. */
.rp-pair {
  display: grid; gap: 14px; align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

/* ── stat cards ── */
.rp-stat {
  position: relative;
  background: var(--e1-bg); border: 1px solid var(--e1-border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-4); min-width: 0; display: flex; flex-direction: column; gap: 6px;
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.rp-stat::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; z-index: 0; background: var(--sheen);
}
.rp-stat > * { position: relative; z-index: 1; }
.rp-stat:hover { transform: translateY(var(--lift)); box-shadow: var(--shadow-2);
                 border-color: var(--hairline-strong); }

/* ── The lead stat ──────────────────────────────────────────────────────────
   Was a SOLID AMBER SLAB: the loudest object on a workspace screen where the
   data should be, and a second saturated moment competing with the Home hero.
   The rule is one per screen.

   It now earns prominence the same way the manager's lead KPI does, by
   sitting a step up the ladder behind an accent ring. Same hierarchy, a
   fraction of the volume. */
.rp-stat--hero {
  background: var(--e2-bg);
  border-color: var(--e2-border);
  box-shadow: var(--shadow-2), var(--glow-ring);
  color: var(--ink);
}
.rp-stat--hero::before { background: var(--sheen-warm); }
.rp-stat--hero:hover { box-shadow: var(--shadow-3), var(--glow-strong); }
.rp-stat--hero .rp-stat__ico { background: var(--accent-wash); color: var(--accent-ink); }
.rp-stat__top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.rp-stat__ico {
  width: 34px; height: 34px; flex: none; border-radius: var(--r-md); display: grid;
  place-items: center; background: var(--wash-strong); color: var(--ink);
}
.rp-stat--hero .rp-stat__ico { background: var(--accent-wash); color: var(--on-accent); }
.rp-stat__ico svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.rp-pill {
  padding: 4px 9px; border-radius: 99px; border: 1px solid transparent;
  font-size: 11px; font-weight: 800; white-space: nowrap; flex: none;
}
/* Same pairing the rest of the app uses: the green from .pill--approved for up,
   steel for down, because this palette has no red and .tag--lost already
   established steel as the negative state. */
.rp-pill--up   { background: var(--success-wash);  color: var(--success);      border-color: var(--success-wash); }
.rp-pill--down { background: rgba(143,154,163,.15); color: var(--ink-muted);     border-color: rgba(143,154,163,.42); }
.rp-pill--flat { background: var(--wash-strong); color: var(--ink-muted); font-weight: 600; }
.rp-stat--hero .rp-pill { background: var(--wash-strong); border-color: var(--hairline-strong); color: var(--ink-subtle); }
.rp-stat__k { margin: 4px 0 0; font-size: 12.5px; font-weight: 700; color: var(--steel); }
.rp-stat--hero .rp-stat__k { color: var(--ink-subtle); }
.rp-stat__v {
  margin: 0; font-size: clamp(21px, 2.2vw, 27px); font-weight: 800;
  letter-spacing: -.03em; line-height: 1.1;
  /* A figure is never cut: in Safari's wider font "473,200 EGP" ended in "…" (v4.240, WebKit audit). The unit
     drops to the next line when the tile is narrow; the number itself never breaks. */
}
.rp-stat__v small { font-size: .5em; font-weight: 700; color: var(--steel); margin-inline-start: 4px; }
.rp-stat--hero .rp-stat__v small { color: var(--ink-subtle); }
.rp-stat__v em { font-style: normal; font-size: .62em; font-weight: 600; color: var(--steel); }
.rp-stat__c { margin: 0; font-size: 11px; color: var(--steel); }
.rp-stat--hero .rp-stat__c { color: var(--ink-subtle); }

/* ── card heads with a subtitle, as the design draws them ── */
/* A title never gives up its room to the controls beside it: the head wraps
   instead, and the controls take the next line. On a phone the Habits head
   carries Breakdown AND the month chip, which squeezed its title to "Customer …". */
.lo-card__h:has(> .rp-h) { flex-wrap: wrap; row-gap: 8px; }
.rp-h { flex: 1 1 150px; min-width: 0; }
.rp-h h2 {
  margin: 0; font-size: 16px; font-weight: 800; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rp-h p { margin: 2px 0 0; font-size: 11.5px; color: var(--steel); }

/* ── customer habits ── */
.rp-key { list-style: none; margin: 0 0 12px; padding: 0; display: flex; gap: 16px; }
.rp-key li { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--steel); }
.rp-key__d { width: 9px; height: 9px; border-radius: 50%; flex: none; display: inline-block; }
.rp-key__d--all { background: rgba(143,154,163,.55); }
.rp-key__d--won { background: var(--amber); }

.rp-plot { display: flex; gap: 10px; }
.rp-plot__y {
  display: flex; flex-direction: column; justify-content: space-between;
  font-size: 10.5px; color: var(--steel); flex: none; height: 220px; text-align: end;
}
.rp-plot__area { position: relative; flex: 1 1 auto; min-width: 0; height: 220px; }
.rp-plot__grid {
  position: absolute; inset: 0 0 24px; display: flex; flex-direction: column;
  justify-content: space-between; pointer-events: none;
}
.rp-plot__grid i { display: block; border-top: 1px dashed var(--line-soft); }
.rp-plot__cols {
  position: absolute; inset: 0; display: grid; gap: 4px;
  grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); align-items: end;
}
.rp-col {
  position: relative; display: flex; flex-direction: column; align-items: center;
  justify-content: flex-end; height: 100%; min-width: 0; border-radius: 8px;
}
.rp-col:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
.rp-col__bars {
  display: flex; align-items: flex-end; justify-content: center; gap: 3px;
  width: 100%; height: calc(100% - 24px);
}
.rp-bar { width: min(13px, 40%); border-radius: 99px 99px 0 0; min-height: 3px; }
.rp-bar--all { background: rgba(143,154,163,.32); }
.rp-bar--won { background: var(--amber); }
.rp-col__m { font-size: 11px; color: var(--steel); height: 24px; line-height: 24px; }

/* The design's dark tooltip. Hover AND focus, so a keyboard reaches it. */
.rp-tip {
  position: absolute; bottom: calc(100% - 46px); left: 50%; translate: -50% 0;
  /* var(--charcoal), not the design's #16191D — that is a light-theme hex and
     this stylesheet's palette is fixed at six. Opaque, because a translucent
     tooltip over the bars it explains is unreadable. */
  background: var(--charcoal); border: 1px solid var(--line); border-radius: 12px;
  padding: 9px 12px; font-size: 11.5px; color: var(--white); line-height: 1.6;
  white-space: nowrap; pointer-events: none; z-index: 3;
  opacity: 0; visibility: hidden; transition: opacity .14s ease, visibility .14s;
  box-shadow: 0 10px 28px var(--shadow-color);
}
.rp-tip b { display: block; font-weight: 800; }
.rp-tip b .rp-key__d { margin-inline-end: 6px; }
.rp-col:hover .rp-tip, .rp-col:focus-visible .rp-tip { opacity: 1; visibility: visible; }
/* The two end columns would hang off the card, so they anchor inward. */
.rp-plot__cols .rp-col:first-child .rp-tip { left: 0; translate: 0 0; }
.rp-plot__cols .rp-col:last-child  .rp-tip { left: auto; right: 0; translate: 0 0; }

/* ── product rings ── */
.rp-prod__body { display: flex; align-items: center; gap: 14px; }
.rp-rings { width: 146px; flex: none; }
.rp-rings svg { width: 100%; height: auto; display: block; }
.rp-prod__fig { min-width: 0; }
.rp-prod__fig b {
  display: block; font-size: 24px; font-weight: 800; letter-spacing: -.03em;
  line-height: 1.1; overflow: hidden; text-overflow: ellipsis;
}
.rp-prod__fig span { display: block; font-size: 11px; color: var(--steel); margin-top: 2px; }

.rp-legend { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.rp-legend li { display: flex; align-items: center; gap: 8px; min-width: 0; }
.rp-legend__d { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.rp-legend__n {
  flex: 1 1 auto; min-width: 0; font-size: 12.5px; font-weight: 600;
  overflow-wrap: anywhere;   /* v4.240 layout audit: wraps, never cut */
}
.rp-legend b { font-size: 12.5px; font-weight: 800; white-space: nowrap; flex: none; }
.rp-legend em {
  font-style: normal; font-size: 11px; color: var(--steel); flex: none;
  width: 36px; text-align: end;
}

/* ── customer growth ── */
.rp-growth__body { display: flex; flex-direction: column; gap: 12px; }
.rp-bubbles { width: 100%; height: auto; display: block; }
.rp-bubbles__t {
  font: 800 11px var(--ui); fill: var(--on-accent);
  paint-order: stroke; letter-spacing: -.02em;
}
.rp-places { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.rp-places li { display: flex; align-items: center; gap: 8px; min-width: 0; }
.rp-src {
  margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--line-soft);
  font-size: 11px; line-height: 1.5; color: var(--steel);
}
.rp-src--warn { color: var(--accent-ink); margin-inline-start: 5px; }

/* ── a stat card that drills in ──
   It is a <button>, so the browser's own button styles have to be undone before
   it can look like the cards beside it. `text-align:start` matters: a button
   centres its text and the figure would not line up with the three cards that
   are still <article>s. */
.rp-stat--act {
  font: inherit; color: inherit; text-align: start; cursor: pointer;
  width: 100%; appearance: none; -webkit-appearance: none;
  transition: transform .14s ease, box-shadow .14s ease, filter .14s ease;
}
.rp-stat--act:hover { transform: translateY(-2px); box-shadow: 0 10px 26px var(--shadow-color); }
.rp-stat--act:active { transform: translateY(0); filter: brightness(.97); }
.rp-stat--act:focus-visible { outline: 3px solid var(--amber); outline-offset: 3px; }
.rp-stat__more {
  display: block; margin-top: 3px; font-weight: 800; letter-spacing: .01em;
  transition: transform .14s ease;
}
.rp-stat--act:hover .rp-stat__more { transform: translateX(3px); }

/* ══ TOTAL SALES BREAKDOWN (in the detail sheet) ═══════════════════════════ */
.sb-title { font-size: 21px; margin: 2px 0 2px; }
.sb-title:focus { outline: none; }
.sb-head {
  margin: 0 0 18px; font-size: 30px; font-weight: 800; letter-spacing: -.02em;
  color: var(--accent-ink);
}
.sb-head small {
  display: block; margin-top: 2px;
  font-size: 12px; font-weight: 600; letter-spacing: 0; color: var(--steel);
}

.sb-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  padding: 14px; margin-bottom: 12px;
}
.sb-card__h { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.sb-card__h h3 { margin: 0; font-size: 14.5px; font-weight: 800; letter-spacing: -.01em; }
.sb-card__h p  { margin: 2px 0 0; font-size: 11.5px; color: var(--steel); }

.sb-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 11px; }
.sb-row { display: grid; grid-template-columns: 1fr auto; gap: 4px 8px; align-items: center; }
.sb-row__h { grid-column: 1 / -1; display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.sb-row__n { font-size: 12.5px; font-weight: 700; min-width: 0; }
.sb-row__n em { font-style: normal; font-weight: 500; color: var(--steel); }
.sb-row__v { font-size: 12.5px; font-weight: 800; white-space: nowrap; }
.sb-row__track { height: 7px; border-radius: 99px; background: rgba(143,154,163,.18); overflow: hidden; }
.sb-row__track > i { display: block; height: 100%; border-radius: 99px; background: var(--amber); }
.sb-row__p { font-size: 11px; font-weight: 700; color: var(--steel); }

.sb-kv { margin: 12px 0 0; display: grid; grid-template-columns: 1fr auto; gap: 4px 10px; }
.sb-kv dt { font-size: 12px; color: var(--steel); }
.sb-kv dd { margin: 0; font-size: 13px; font-weight: 800; text-align: end; }
.sb-kv dd em { font-style: normal; font-weight: 500; font-size: 11px; color: var(--steel); }

/* The period switch. Same idea as the sign-in tabs: the active one carries the
   accent, and it is two real buttons, not a styled div. */
.sb-seg { display: flex; flex: none; border: 1px solid var(--line); border-radius: 99px; padding: 3px; }
.sb-seg__b {
  border: 0; background: none; cursor: pointer; border-radius: 99px;
  padding: 5px 11px; font: 700 11.5px var(--ui); color: var(--steel);
  transition: background-color .16s ease, color .16s ease;
}
.sb-seg__b.is-on { background: var(--amber); color: var(--on-accent); }
.sb-seg__b:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

/* The trend chart. Bars are flex children with a percentage height, so the
   chart reflows to any width without recomputing an SVG viewBox. */
.sb-bars { display: flex; align-items: flex-end; gap: 3px; height: 150px; }
.sb-bars__c { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; justify-content: flex-end; height: 100%; }
.sb-bars__b {
  position: relative; display: block; width: 100%; min-height: 2px;
  border-radius: 4px 4px 0 0; background: var(--amber);
}
.sb-bars__b.is-zero { background: rgba(143,154,163,.22); }
.sb-bars__x {
  margin-top: 5px; font-size: 9.5px; color: var(--steel);
  text-align: center; white-space: nowrap; overflow: hidden;
}
/* Tooltip on hover and on keyboard focus of the column. */
.sb-bars__t {
  position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  padding: 5px 8px; border-radius: 7px; background: var(--charcoal);
  border: 1px solid var(--line); color: var(--white);
  font-size: 10.5px; font-weight: 600; white-space: nowrap;
  opacity: 0; pointer-events: none; transition: opacity .12s ease; z-index: 3;
}
.sb-bars__c:hover .sb-bars__t { opacity: 1; }

/* ── proposal list (Total Proposals sheet) ── */
.sp-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.sp-tab {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); background: none; cursor: pointer;
  border-radius: 99px; padding: 6px 10px 6px 12px;
  font: 700 11.5px var(--ui); color: var(--steel);
  transition: background-color .16s ease, color .16s ease, border-color .16s ease;
}
.sp-tab:hover { border-color: var(--accent-ink); color: var(--white); }
.sp-tab.is-on { background: var(--amber); border-color: var(--accent-ink); color: var(--on-accent); }
.sp-tab:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
.sp-tab__n {
  min-width: 18px; padding: 1px 5px; border-radius: 99px; text-align: center;
  background: rgba(143,154,163,.2); font-size: 10.5px; font-weight: 800;
}
.sp-tab.is-on .sp-tab__n { background: rgba(35,35,35,.18); }
/* A state the app cannot produce. Dimmed rather than hidden: the gap is the
   answer, and a filter that silently is not there reads as an oversight. */
.sp-tab.is-absent { opacity: .5; border-style: dashed; }

.sp-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.sp-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 0; border-top: 1px solid var(--line-soft); min-width: 0;
}
/* The proposals sheet makes the <li> itself the row; the accounts sheet wraps a
   <button> in one. A bare `:first-child` matches that button every time and
   would strip the divider from every account. */
.sp-list > .sp-row:first-child,
.sp-list > li:first-child > .sp-row { border-top: 0; }
.sp-row__main { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sp-row__c {
  font-size: 13px; font-weight: 700; color: var(--white);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sp-row__m {
  font-size: 11px; color: var(--steel);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sp-row__r { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.sp-row__r b { font-size: 13px; font-weight: 800; white-space: nowrap; }
.sp-pill {
  padding: 2px 8px; border-radius: 99px; font-size: 10px; font-weight: 800;
  letter-spacing: .02em; white-space: nowrap; border: 1px solid transparent;
}
/* The three states the lifecycle actually has, in the same colours the
   Proposals-by-status dial uses, so the two cannot be read as different data. */
/* Colours: the shared proposal-status block, with .pill--approved. */

/* Product sheet bullets — key features and applications, straight off the
   technical sheet. A list, because they are a list; running them together with
   separators is how a spec sheet becomes a paragraph nobody reads. */
.pbul { margin: 0; padding-inline-start: 18px; display: flex; flex-direction: column; gap: 5px; }
.pbul li { font-size: 13px; line-height: 1.6; color: var(--steel); }
.pbul li::marker { color: var(--accent-ink); }

/* ── the drill-in affordance on a PANEL header ── */
.rp-more {
  flex: none; border: 1px solid var(--line); background: none; cursor: pointer;
  border-radius: 99px; padding: 5px 11px;
  font: 700 11px var(--ui); color: var(--steel);
  display: inline-flex; align-items: center; gap: 5px;
  transition: color .16s ease, border-color .16s ease, background-color .16s ease;
}
.rp-more:hover { color: var(--on-accent); background: var(--amber); border-color: var(--accent-ink); }
.rp-more:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
.rp-more span { transition: transform .16s ease; }
.rp-more:hover span { transform: translateX(3px); }

/* ── product performance (Product Statistic sheet) ── */
/* Two bars in one track: proposed behind, agreed in front. Absolute so they
   share an origin — side by side they would read as two separate measures. */
.pb-track { position: relative; }
.pb-track > i { position: absolute; inset-block: 0; inset-inline-start: 0; display: block; border-radius: 99px; }
.pb-prop { background: rgba(247,161,26,.28); }
.pb-won  { background: var(--amber); }
.pb-slow {
  margin-inline-start: 6px; padding: 1px 6px; border-radius: 99px;
  background: rgba(247,161,26,.16); border: 1px solid rgba(247,161,26,.4);
  color: var(--accent-ink); font-size: 9.5px; font-weight: 800;
  letter-spacing: .04em; text-transform: uppercase;
}

/* ── customer growth / habits sheets ── */
.cg-big {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  padding: 12px 0 16px; margin-bottom: 4px;
  border-bottom: 1px solid var(--line-soft);
}
.cg-big__v { font-size: 38px; font-weight: 800; letter-spacing: -.03em; color: var(--accent-ink); }
.cg-big__k { flex: 1 1 180px; font-size: 12px; line-height: 1.5; color: var(--steel); }
.cg-big__k b { color: var(--white); font-weight: 800; }

.ch-row { align-items: flex-start; }
.ch-mix { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.ch-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; border-radius: 99px;
  background: rgba(247,161,26,.12); border: 1px solid rgba(247,161,26,.3);
  font-size: 10.5px; font-weight: 600; color: var(--white); white-space: nowrap;
}
.ch-chip b { color: var(--accent-ink); font-weight: 800; }
.ch-chip--none { background: none; border-style: dashed; border-color: var(--line); color: var(--steel); }

/* ── volume breakdown (Volume Sold sheet) ── */
.vb-u { font-size: .42em; font-weight: 700; color: var(--steel); margin-inline-start: 5px; }
/* Sits under the bar with the row's own count, so a 2% slice still says whether
   it is one big order or twenty small ones. */
.vb-n { grid-column: 1 / -1; font-size: 10.5px; color: var(--steel); margin-top: -1px; }

/* ── account list (Accounts sheet) ── */
.ab-search { position: relative; display: flex; margin-bottom: 14px; }
.ab-search svg {
  position: absolute; inset-inline-start: 13px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; pointer-events: none;
  fill: none; stroke: var(--steel); stroke-width: 2; stroke-linecap: round;
}
.ab-search__i {
  width: 100%; min-height: 44px; padding: 0 14px 0 38px;
  background: var(--brown); color: var(--white);
  border: 1px solid var(--line); border-radius: 12px;
  font: 14px var(--ui);
}
[dir="rtl"] .ab-search__i { padding: 0 38px 0 14px; }
.ab-search__i::placeholder { color: var(--steel); }
.ab-search__i:focus { outline: 0; border-color: var(--accent-ink); box-shadow: 0 0 0 3px rgba(247,161,26,.18); }
/* The UA's own clear button sits on a light chrome that this field does not
   have, so it renders as a dark smudge. */
.ab-search__i::-webkit-search-cancel-button { filter: invert(1) opacity(.5); }

/* The row is a button here (it opens the account), so the button defaults have
   to be undone — .sp-row assumes a list item. */
.ab-row {
  width: 100%; border: 0; background: none; cursor: pointer;
  font: inherit; color: inherit; text-align: start;
  padding: 11px 0;
}
.ab-row:hover .sp-row__c { color: var(--accent-ink); }
.ab-row:focus-visible { outline: 2px solid var(--amber); outline-offset: -2px; border-radius: 8px; }
.ab-row__meta { display: flex; align-items: center; gap: 6px; margin-top: 5px; flex-wrap: wrap; }

.ab-tier {
  padding: 2px 8px; border-radius: 6px; font-size: 10px; font-weight: 800;
  background: rgba(143,154,163,.18); color: var(--white); white-space: nowrap;
}
/* A classification the book actually records and one this app worked out are
   not the same claim, so they do not get the same weight. */
.ab-tier.is-derived { background: none; border: 1px dashed var(--line); color: var(--steel); font-weight: 600; }
.ab-tier.is-none { background: none; color: var(--steel); font-weight: 600; padding-inline: 0; }

.ab-since { font-size: 10.5px; color: var(--steel); white-space: nowrap; }
.ab-cold { color: var(--accent-ink); }

/* Account stages. WON and LOST are the two that carry a verdict, so they are
   the two that get a colour; the rest are stages on the way there. */
.sp-pill--stWON  { background: var(--success-wash); color: var(--success); border-color: var(--success-wash); }
.sp-pill--stLOST { background: rgba(196,52,43,.14); color: #E8837C; border-color: rgba(196,52,43,.4); }
.sp-pill--stNEW, .sp-pill--stOPEN, .sp-pill--stTDS,
.sp-pill--stOFFER, .sp-pill--stTRIAL {
  background: rgba(143,154,163,.16); color: var(--steel); border-color: rgba(143,154,163,.34);
}

.sb-empty { margin: 0; font-size: 12px; line-height: 1.6; color: var(--steel); }
.sb-src {
  margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--line-soft);
  font-size: 11px; line-height: 1.55; color: var(--steel);
}
.sb-src--warn { color: var(--accent-ink); }
/* The "this is not a payment ledger" note. Boxed, because it is a statement
   about what the data ISN'T, and that should not read as a caption. */
.sb-src--note {
  border: 1px solid rgba(247,161,26,.34); background: rgba(247,161,26,.07);
  border-radius: 10px; padding: 10px 11px; margin-top: 12px;
}
.sb-src--note b { color: var(--white); font-weight: 800; }

/* ── narrower than the design ── */
@media (max-width: 1180px) { .rp-grid { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 620px) {
  .rp-stats { grid-template-columns: minmax(0, 1fr); }
  .rp-plot__y, .rp-plot__area { height: 190px; }
  .rp-prod__body { flex-direction: column; align-items: flex-start; }
  .sb-bars { height: 120px; }
}

/* ══ AVATAR PICKER ══════════════════════════════════════════════════════════
   The header circle can carry initials, an emoji, or a picture from the
   device. The overlay is built in JS and appended to <body>, so neither page's
   markup changes and the rep app and manager dashboard cannot drift apart.
   ═════════════════════════════════════════════════════════════════════════ */
/* The circle is a button in all but name — say so to a pointer and a keyboard. */
.avatar { cursor: pointer; border: 0; padding: 0; font-family: inherit; }
.avatar:focus-visible { outline: 2px solid var(--white); outline-offset: 2px; }
/* A picture fills the circle and is cropped by it. Centre-cropped square
   already, so this only guards against an odd stored size. */
.avatar--img {
  background-size: cover; background-position: center; background-repeat: no-repeat;
  color: transparent;
}
/* An emoji needs room: at the initials' 13px it reads as a smudge. */
.avatar--emoji { font-size: 20px; line-height: 1; background: rgba(143,154,163,.18); }

.avp { position: fixed; inset: 0; z-index: 90; display: grid; place-items: center; }
.avp__scrim { position: absolute; inset: 0; background: rgba(0,0,0,.6); }
.avp__box {
  /* 100%, not 100vw: .avp is position:fixed inset:0, so 100% is the viewport
     already — and without the scrollbar 100vw would have added back. */
  position: relative; width: min(380px, calc(100% - 32px));
  max-height: min(560px, calc(100dvh - 32px)); overflow-y: auto;
  background: var(--charcoal); border: 1px solid var(--line); border-radius: 18px;
  padding: 20px; box-shadow: 0 24px 60px var(--shadow-color);
}
.avp__t { margin: 0; font-size: 18px; font-weight: 800; }
.avp__s { margin: 6px 0 16px; font-size: 12.5px; line-height: 1.55; color: var(--steel); }

.avp__grid { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); gap: 6px; }
@media (max-width: 400px) { .avp__grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
.avp__e {
  aspect-ratio: 1; display: flex; align-items: center; justify-content: center; padding: 0; font-size: 20px;
  border: 1px solid transparent; border-radius: 12px;
  background: rgba(143,154,163,.12); cursor: pointer; line-height: 1;
  /* flex, not grid: WebKit set the emoji (bare text in a grid button) at the top of its tile */
}
.avp__e:hover { background: rgba(247,161,26,.2); border-color: var(--accent-ink); }
.avp__e:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

.avp__err { margin: 12px 0 0; font-size: 12px; color: var(--accent-ink); }

/* The file input itself is hidden, but only visually — `display:none` would
   take it out of the tab order and the label would be unreachable by keyboard. */
.avp__file {
  display: flex; align-items: center; justify-content: center; min-height: var(--tap);
  margin-top: 14px; border-radius: 12px; cursor: pointer;
  background: var(--amber); color: var(--on-accent); font: 800 13.5px var(--ui);
}
.avp__file input {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.avp__file:hover { background: var(--vivid); }
.avp__file:focus-within { outline: 2px solid var(--white); outline-offset: 2px; }

.avp__reset, .avp__done {
  display: block; width: 100%; min-height: var(--tap); margin-top: 8px;
  border-radius: 12px; cursor: pointer; font: 700 13px var(--ui);
  background: none; border: 1px solid var(--line); color: var(--white);
}
.avp__reset:hover, .avp__done:hover { background: var(--wash); }
.avp__reset:focus-visible, .avp__done:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

/* ── Orders: the Open / Settled switch ────────────────────────────────────── */
/* Live Orders and Order History were two sidebar entries showing two halves of
   one list. They were never the same rows, but the counts matched in demo data
   and they read as duplicates. One entry, one switch. */
.lo-seg {
  display: inline-flex; gap: 4px; padding: 4px; margin-bottom: 14px;
  background: rgba(143,154,163,.12); border: 1px solid var(--line);
  border-radius: 99px; max-width: 100%;
}
.lo-seg__b {
  display: inline-flex; align-items: center; gap: 7px; min-height: 36px;
  padding: 0 15px; border: 0; border-radius: 99px; cursor: pointer;
  background: none; color: var(--steel); font: 700 13px var(--ui);
  white-space: nowrap;
}
.lo-seg__b em {
  font-style: normal; font-size: 11px; font-weight: 800;
  padding: 2px 7px; border-radius: 99px; background: rgba(143,154,163,.2);
}
.lo-seg__b:hover { color: var(--white); }
/* Charcoal on amber, as everywhere else an orange fill carries text. */
.lo-seg__b.is-on { background: var(--amber); color: var(--on-accent); }
.lo-seg__b.is-on em { background: rgba(35,35,35,.18); }
.lo-seg__b:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }


/* ── Products: the axis toggle above the chip strip ── */
.catbar { display: flex; align-items: center; gap: 10px; margin: 10px 0 2px; flex-wrap: wrap; }
.seg {
  display: flex; gap: 2px; padding: 3px; border-radius: 99px;
  border: 1px solid var(--line); background: rgba(143,154,163,.07);
}
.seg__b {
  border: 0; background: none; color: var(--steel); cursor: pointer;
  border-radius: 99px; padding: 8px 14px; font: 600 12.5px/1 var(--ui);
  min-height: 36px;
}
.seg__b.is-on { background: var(--amber); color: var(--on-accent); }
.seg__b:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

/* ── Industries, on the product sheet ── */
.ind { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.ind__i {
  display: flex; flex-direction: column; gap: 2px;
  border: 1px solid var(--line); border-radius: 10px; padding: 7px 10px;
  font-size: 12.5px; color: var(--steel);
}
/* A sector the sheet actually names reads as a fact; an inferred one reads as
   a suggestion. Same list, deliberately not the same weight. */
.ind__i.is-stated { border-color: rgba(247,161,26,.42); color: var(--white); }
.ind__m { font: 600 9.5px/1 var(--mono); letter-spacing: .04em; color: var(--steel); }
.ind__i.is-stated .ind__m { color: var(--accent-ink); }
.ind__note { font-size: 11.5px; line-height: 1.6; color: var(--steel); margin: 9px 0 0; }

/* The food-grade distinction. Loud on purpose: this is the one claim in the
   app that a rep could repeat to a customer and land Petromix in a compliance
   argument. */
.ind__food {
  font-size: 12px; line-height: 1.6; margin: 10px 0 0;
  padding: 9px 11px; border-radius: 10px;
  border: 1px solid rgba(244,123,11,.45);
  background: rgba(244,123,11,.09); color: var(--white);
}
.ind__food b { color: var(--accent-ink); }
.ind__food.is-approved { border-color: rgba(247,161,26,.45); background: rgba(247,161,26,.09); }
.ind__food.is-approved b { color: var(--accent-ink); }

/* The "Has documents" filter chip, marked out from the family chips beside it
   because it answers a different question. */
.chip--docs { border-color: rgba(247,161,26,.45); color: var(--accent-ink); }
.chip--docs em {
  font-style: normal; font-weight: 700; margin-inline-start: 6px;
  padding: 2px 6px; border-radius: 99px;
  background: rgba(247,161,26,.18);
}
.chip--docs.is-on em { background: rgba(35,35,35,.20); }
/* A sector with nothing in it is shown and disabled rather than hidden: "we
   have no marine products" is information, and a category that silently
   vanishes just looks like a bug. */
.chip:disabled { opacity: .4; cursor: not-allowed; }
.chip em {
  font-style: normal; font-weight: 700; margin-inline-start: 6px;
  padding: 2px 6px; border-radius: 99px; background: rgba(143,154,163,.18);
}
.chip.is-on em { background: rgba(35,35,35,.20); }

/* The paperwork badges on a product LIST row. Small, because they sit under a
   product name and must not compete with it — but present, because the whole
   point of the vault is that a rep can see what they can send. */
.row__docs { display: flex; gap: 4px; margin-top: 5px; }
.row__doc {
  font: 700 9px/1 var(--mono); letter-spacing: .05em;
  padding: 4px 6px; border-radius: 5px;
  background: rgba(143,154,163,.16); color: var(--steel);
}
.row__doc--tds { background: rgba(247,161,26,.18); color: var(--accent-ink); }
.row__doc--oem { background: rgba(244,123,11,.18); color: var(--accent-ink); }

/* ══ DOCUMENT VAULT ════════════════════════════════════════════════════════
   The paperwork a buyer asks for, on the product sheet. A row is a document:
   kind badge, title, whether the file is actually there, and the three things
   a rep does with it — open it, send it, mail it. */
.dv { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }

/* Wraps on the ROW's own width, not the viewport's. The sheet is a fixed-width
   panel, so a viewport media query asks the wrong question — a wide desktop
   still renders these three buttons into a narrow column. Giving the title a
   flex-basis lets the actions drop to their own line exactly when the title
   would otherwise be crushed. */
.dv__row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  border: 1px solid var(--line); border-radius: 12px; padding: 9px 10px;
}

/* The kind is the first thing scanned: a safety officer wants the MSDS and
   nothing else, so the badge carries the distinction, not just the title. */
.dv__k {
  flex: none; min-width: 46px; text-align: center;
  font: 700 10px/1 var(--mono); letter-spacing: .06em;
  padding: 6px 6px; border-radius: 6px;
  background: rgba(143,154,163,.16); color: var(--steel);
}
.dv__k--tds  { background: rgba(247,161,26,.18); color: var(--accent-ink); }
.dv__k--msds,
.dv__k--sds  { background: rgba(143,154,163,.20); color: #C6CFD6; }
.dv__k--oem  { background: rgba(244,123,11,.18); color: var(--accent-ink); }

/* The title is the preview: tapping it opens the PDF. A separate "Open" button
   would have cost a quarter of the row's width to duplicate what everyone
   already tries first. */
.dv__open {
  flex: 1 1 130px; min-width: 0; display: flex; flex-direction: column; gap: 2px;
  background: none; border: 0; padding: 0; margin: 0; cursor: pointer;
  text-align: start; font: inherit; color: inherit;
}
.dv__open:hover:not(:disabled) .dv__t { color: var(--accent-ink); }
.dv__open:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; border-radius: 4px; }
.dv__open:disabled { cursor: default; }
.dv__t { font-size: 13px; line-height: 1.35; color: var(--white); }
.dv__s { font-size: 11px; line-height: 1.3; color: var(--steel); }

.dv__act { flex: none; display: flex; gap: 6px; }
.dv__b {
  border: 1px solid var(--line); background: none; color: var(--steel);
  border-radius: 99px; padding: 6px 11px; cursor: pointer;
  font: 600 12px/1 var(--ui);
}
.dv__b:hover:not(:disabled) { border-color: var(--accent-ink); color: var(--white); }
/* Sending it is the verb this screen exists for. */
.dv__b--go:not(:disabled) { border-color: var(--accent-ink); color: var(--accent-ink); }
.dv__b--go:hover:not(:disabled) { background: var(--amber); color: var(--on-accent); }
.dv__b:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
.dv__b:disabled { opacity: .38; cursor: not-allowed; }

/* A file that has not been uploaded says so and cannot be sent. It is still
   listed, because "this product has an MSDS and we have not loaded it" is
   information the rep needs before a customer asks for it. */
.dv__row.is-missing { border-style: dashed; }
.dv__row.is-missing .dv__k { opacity: .45; }
.dv__row.is-missing .dv__t { color: var(--steel); }
.dv__row.is-missing .dv__s { color: var(--accent-ink); }
.dv__row.is-missing .dv__open:hover .dv__t { color: var(--steel); }

.dv__all { margin-top: 10px; }
.dv__none { font-size: 13px; line-height: 1.6; color: var(--steel); margin: 0; }

/* The TITLE takes the slack, which pushes the buttons right while they share a
   line with it — and then leaves them flush left once they wrap onto their own.
   An `margin-inline-start: auto` here did the first job and broke the second:
   on the wrapped line it shoved the group right until "Email" hung off the
   edge of the sheet. Letting the title grow gets both cases from one rule. */
.dv__act { flex: 0 0 auto; }
/* On a phone these three carry the whole feature and get tapped one-handed in
   a van, so they take the full line and meet --tap. They measured 32px high
   before this, well under the floor the rest of the app holds to. */
@media (max-width: 460px) {
  .dv__act { width: 100%; }
  .dv__b { flex: 1 1 0; min-height: var(--tap); padding: 6px; }
}



/* ══════════════════════════════════════════════════════════════════════════
   REFERENCE LAYOUT PATTERNS
   Taken from the supplied mock, which uses shapes this app did not have:

     · a centred profile block on the bare canvas, no card around it
     · every setting as its OWN rounded row, rather than grouped under
       headings inside one panel
     · circular logo chips in list rows, not rounded squares
     · a segmented control whose selected pill is WHITE on a dark track

   The first two are what the More screen was missing; it was three panels
   with <h2>s, which reads as a form rather than as settings.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Screen header ────────────────────────────────────────── */
/* Centred title with an action on the right, which is how the reference opens
   every screen. The rep app had no per-screen title at all; the top bar
   carries the rep's name instead, so this is additive rather than a move.
   The left spacer is the same width as the action button so the title is
   optically centred rather than just text-align:center inside a flex row. */
.shead { display: flex; align-items: center; gap: var(--space-3);
         padding: var(--space-1) 0 var(--space-4); }
.shead__sp, .shead__act { width: 38px; height: 38px; flex: none; }
.shead__t { flex: 1 1 auto; margin: 0; text-align: center;
            font: 600 19px/1.2 var(--font-ui); letter-spacing: -.02em; color: var(--ink); }
.shead__act {
  display: grid; place-items: center; border: 0; cursor: pointer;
  border-radius: var(--r-pill); background: none; color: var(--ink-subtle);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.shead__act:hover  { background: var(--wash); color: var(--ink); }
.shead__act:active { transform: scale(var(--press)); }
.shead__act svg { width: 19px; height: 19px; fill: none; stroke: currentColor;
                  stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }

/* ── Profile block ─────────────────────────────────────── */
/* Ringed, not filled. The first attempt used a 96px amber gradient slab, which
   made the avatar the loudest object on the screen and spent the one accent on
   a decoration. The reference uses a smaller photo circle with a hairline
   around it, so the face is the subject and the chrome disappears. */
.prof { display: flex; flex-direction: column; align-items: center; gap: 2px;
        padding: 0 0 var(--space-6); }
.prof__av {
  width: 84px; height: 84px; border-radius: var(--r-pill);
  display: grid; place-items: center; overflow: hidden;
  background: var(--e2-bg);
  /* A clean light ring sitting ON the circle, which is the treatment in the
     reference. The first version added a canvas-coloured halo underneath as
     well, and that read as the avatar being punched INTO the page rather than
     resting on it. One ring, nothing behind it. */
  border: 2px solid var(--hairline-strong);
  color: var(--ink); font: 600 26px/1 var(--font-mono); letter-spacing: -.02em;
  margin-bottom: var(--space-3); padding: 0; cursor: pointer;
  transition: transform var(--dur-fast) var(--ease), border-color var(--dur) var(--ease);
}
.prof__av:hover  { border-color: var(--accent); }
.prof__av:active { transform: scale(var(--press)); }
.prof__av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.prof__name { margin: 0; font: 600 18px/1.2 var(--font-ui); letter-spacing: -.02em;
              color: var(--ink); }
.prof__mail { margin: 2px 0 0; font: 400 13px/1.4 var(--font-ui); color: var(--ink-subtle); }

/* ── Setting rows ──────────────────────────────────────── */
.srows { display: flex; flex-direction: column; gap: var(--space-2); }
.srow {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4); width: 100%; min-height: 54px;
  padding: var(--space-3) var(--space-4);
  background: var(--e1-bg); border: 1px solid var(--e1-border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-1);
  text-align: start;
  transition: transform var(--dur-fast) var(--ease),
              box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.srow__k { font: 500 14.5px/1.35 var(--font-ui); color: var(--ink); min-width: 0; }
.srow__r { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.srow__v { font: 400 14px/1.35 var(--font-ui); color: var(--ink-subtle);
           white-space: nowrap; }
.srow__v--mute { color: var(--ink-tertiary); }
/* Only rows that DO something get the press feedback; a row showing a count
   does nothing when tapped and should not pretend otherwise. */
.srow--act { cursor: pointer; }
.srow--act:hover  { border-color: var(--hairline-strong); box-shadow: var(--shadow-2); }
.srow--act:active { transform: scale(var(--press)); }
.srow__go { width: 17px; height: 17px; flex: none; fill: none; stroke: currentColor;
            stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
            color: var(--ink-tertiary); }
.srow--danger .srow__k { color: var(--danger); font-weight: 600; }
.srow--danger .srow__go { color: var(--danger); }
/* The chevron points the way the language reads. */
[dir="rtl"] .srow__go { transform: scaleX(-1); }

/* ── Circular list chips ───────────────────────────────────────────────── */
/* The mock's transaction rows use round merchant logos. A rounded square
   reads as an app icon; a circle reads as an identity, which is what a
   product initial or a company monogram is. */
.row__ini { border-radius: var(--r-pill); }

/* ── Segmented control, white pill ─────────────────────────────────────── */
/* The mock's Spending/Limits control puts a WHITE pill behind the selection on
   a dark track. Amber was being spent here on something that is not an action,
   which the one-accent rule does not allow. */
.lang { display: inline-flex; padding: 4px; gap: 2px;
        background: var(--canvas); border: 1px solid var(--hairline);
        border-radius: var(--r-pill); }
.lang__b {
  border: 0; cursor: pointer; white-space: nowrap;
  padding: 7px 15px; border-radius: var(--r-pill);
  background: none; color: var(--ink-subtle);
  font: 500 13px/1 var(--font-ui);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.lang__b:hover  { color: var(--ink); }
.lang__b:active { transform: scale(var(--press)); }
.lang__b.is-on  { background: var(--ink); color: var(--canvas); font-weight: 600; }

/* ── "App updated" ────────────────────────────────────────────────────────────
   Shown once, after the page reloads itself onto a new version, and stays until
   OK. The scrim is light: nothing behind it is blocked for long, and it is a
   notice, not an error. */
.upd {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: flex-start; justify-content: center;
  padding: calc(var(--safe-t, 0px) + 72px) 16px 16px;
  background: rgba(0, 0, 0, .35);
}
.upd__card {
  width: min(380px, 100%); padding: 20px 20px 18px; border-radius: var(--r-xl, 20px);
  background: var(--e3-bg); border: 1px solid var(--hairline-strong); box-shadow: var(--shadow-2);
  color: var(--ink); font-family: var(--ui);
}
.upd__t { margin: 0 0 6px; font-size: 17px; font-weight: 800; }
.upd__m { margin: 0 0 16px; font-size: 14px; line-height: 1.5; color: var(--ink-muted); }
.upd__ok { width: 100%; }

/* ══ PRICE CALCULATOR ═══════════════════════════════════════════════════════
   The supplied calculator's layout, on the app's tokens and typefaces. The
   design had its own palette (a fixed dark shell around white cards) and
   pulled Barlow from Google Fonts; the shell would ignore light mode and the
   font would vanish offline, so neither came across. Its structure did:
   numbered sections, pack tiles, a stepper over a slider, a three-cell
   readout, delivery tiles, and a price panel with its breakdown. */
.pc { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.pc__body { display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start; }
.pc-card {
  background: var(--e1-bg); border: 1px solid var(--hairline); border-radius: var(--r-lg);
  box-shadow: var(--shadow-1); color: var(--ink); min-width: 0;
}
.pc-in  { flex: 999 1 560px; display: flex; flex-direction: column; }
.pc-out { flex: 1 1 360px; overflow: hidden; display: flex; flex-direction: column; position: sticky; top: 16px; }

.pc-sec { padding: 22px 24px 24px; display: flex; flex-direction: column; gap: 14px; border-bottom: 1px solid var(--wash); }
.pc-sec:last-child { border-bottom: 0; }
.pc-sec__h { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.pc-sec__t { display: flex; align-items: baseline; gap: 12px; }
.pc-sec__t h2 { margin: 0; font-size: 13px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
.pc-no { font-family: var(--mono); font-size: 13px; font-weight: 700; color: var(--accent-ink); }
.pc-hint { margin: 0; font-size: 12.5px; font-weight: 500; color: var(--ink-subtle); }
.pc-k { display: block; font-size: 10.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-subtle); }

.pc-prod { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 10px; }
.pc-sel {
  width: 100%; min-width: 0; height: 46px; padding: 0 12px; border-radius: 10px;
  border: 1px solid var(--hairline-strong); background: var(--e2-bg); color: var(--ink);
  font: 600 14px/1.25 var(--ui);
}
.pc-sel:focus-visible { outline: 2px solid var(--accent-focus); outline-offset: 1px; }
.pc-zone { display: flex; flex-direction: column; gap: 6px; }

.pc-seg { display: flex; gap: 3px; padding: 3px; border-radius: 10px; background: var(--wash); }
.pc-seg__b {
  height: 34px; padding: 0 14px; border: 0; border-radius: 8px; background: none; cursor: pointer;
  color: var(--ink-subtle); font: 700 13px/1.25 var(--ui);
}
.pc-seg__b.is-on { background: var(--accent); color: var(--on-accent); }

.pc-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.pc-grid--2 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.pc-opt {
  display: flex; align-items: center; gap: 12px; min-height: 64px; padding: 10px 14px; text-align: start;
  border: 2px solid var(--hairline-strong); border-radius: 10px; background: var(--e1-bg); color: var(--ink);
  cursor: pointer; font-family: var(--ui);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.pc-opt:hover { border-color: var(--ink-tertiary); }
.pc-opt.is-on { border-color: var(--accent); background: var(--accent-wash); }
.pc-opt:focus-visible { outline: 2px solid var(--accent-focus); outline-offset: 2px; }
.pc-opt--del { min-height: 72px; }
.pc-opt__n { display: block; font-size: 15px; font-weight: 800; }
.pc-opt__s { display: block; font-size: 12.5px; font-weight: 600; color: var(--ink-subtle); }
.pc-ico {
  width: 40px; height: 40px; flex: none; border-radius: 8px; display: flex; align-items: center; justify-content: center;
  background: var(--wash); border: 1px solid var(--hairline); color: var(--ink);
}
.pc-ico--ink { background: var(--ink); color: var(--e3-bg); border-color: transparent; }
.pc-ico svg, .pc-step svg, .pc-cta svg, .pc-ghost svg, [data-of-act="more"] svg {
  width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}

.pc-qty { display: flex; flex-direction: column; gap: 10px; padding: 16px 18px; border-radius: 10px; background: var(--wash); border: 1px solid var(--hairline); }
.pc-qty__h { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.pc-qty__l { display: flex; flex-direction: column; gap: 2px; }
.pc-qty__l b { font-size: 15px; }
.pc-stepper { display: flex; align-items: center; gap: 8px; }
.pc-step {
  width: 46px; height: 46px; border-radius: 10px; border: 1px solid var(--hairline-strong); background: var(--e1-bg);
  color: var(--ink); display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.pc-step svg { width: 18px; height: 18px; stroke-width: 2.4; }
.pc-step:hover { background: var(--wash-strong); }
.pc-qty__v {
  min-width: 70px; height: 46px; display: flex; align-items: center; justify-content: center; border-radius: 10px;
  border: 1px solid var(--ink); background: var(--e1-bg); font: 800 22px/1 var(--mono); font-variant-numeric: tabular-nums;
}
.pc-ticks { display: flex; justify-content: space-between; font: 700 11.5px/1.25 var(--mono); color: var(--ink-subtle); }

.pc-range { --fill: 20%; -webkit-appearance: none; appearance: none; width: 100%; height: 32px; margin: 0; background: none; cursor: pointer; }
.pc-range::-webkit-slider-runnable-track {
  height: 8px; border-radius: 4px;
  background: linear-gradient(var(--accent), var(--accent)) 0 0 / var(--fill) 100% no-repeat, var(--wash-strong);
}
.pc-range::-moz-range-track { height: 8px; border-radius: 4px; background: var(--wash-strong); }
.pc-range::-moz-range-progress { height: 8px; border-radius: 4px; background: var(--accent); }
.pc-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 26px; height: 26px; margin-top: -9px; border-radius: 50%;
  background: var(--ink); border: 4px solid var(--accent); box-shadow: 0 2px 6px rgba(0, 0, 0, .3);
}
.pc-range::-moz-range-thumb { width: 18px; height: 18px; border-radius: 50%; background: var(--ink); border: 4px solid var(--accent); }
.pc-range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--accent-focus); }

.pc-readout { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border: 1px solid var(--hairline-strong); border-radius: 10px; overflow: hidden; }
.pc-readout > div { padding: 12px 16px; display: flex; flex-direction: column; gap: 4px; border-inline-end: 1px solid var(--hairline-strong); min-width: 0; }
.pc-readout > div:last-child { border-inline-end: 0; }
.pc-readout b { font: 800 24px/1 var(--mono); line-height: 1; font-variant-numeric: tabular-nums; }
.pc-readout small { font-size: 12.5px; color: var(--ink-subtle); }

.pc-out__head {
  padding: 13px 22px; display: flex; justify-content: space-between; align-items: center; gap: 10px;
  background: var(--wash-strong);
}
.pc-out__head span:first-child { font-size: 11.5px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
.pc-terms { font-size: 12px; font-weight: 700; padding: 3px 10px; border-radius: 6px; border: 1px solid var(--hairline-strong); white-space: nowrap; }
.pc-price { padding: 22px 22px 18px; display: flex; flex-direction: column; gap: 14px; border-bottom: 1px solid var(--wash); }
.pc-total { display: flex; align-items: flex-start; gap: 8px; }
.pc-total__cur { font: 700 20px/1 var(--mono); color: var(--ink-subtle); padding-top: 10px; }
.pc-total__v { font: 800 clamp(44px, 6vw, 64px)/1 var(--mono); line-height: 1; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.pc-units { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border: 1px solid var(--hairline-strong); border-radius: 10px; overflow: hidden; }
.pc-units > div { padding: 10px 14px; display: flex; flex-direction: column; gap: 2px; }
.pc-units > div:first-child { border-inline-end: 1px solid var(--hairline-strong); }
.pc-units > div.is-primary { background: var(--accent-wash); }
.pc-units b { font: 800 19px/1 var(--mono); font-variant-numeric: tabular-nums; }

.pc-bd { padding: 16px 22px; display: flex; flex-direction: column; gap: 12px; font-size: 14px; }
.pc-row { display: flex; justify-content: space-between; gap: 12px; }
.pc-row > span:first-child { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.pc-row > span:last-child { font-weight: 700; font-family: var(--mono); white-space: nowrap; }
.pc-row small { font-size: 12px; color: var(--ink-subtle); }
.pc-row--total { padding-top: 12px; border-top: 2px solid var(--ink); font-size: 16px; font-weight: 800; }
.pc-nudge { padding: 10px 12px; border: 1px dashed var(--hairline-strong); border-radius: 8px; font-size: 13px; color: var(--ink-muted); }
.pc-acts { padding: 4px 22px 22px; display: flex; flex-direction: column; gap: 10px; }
.pc-cta { width: 100%; min-height: 54px; gap: 10px; font-size: 16px; }
.pc-ghost { width: 100%; min-height: 48px; }
.pc-fine { margin: 0; font-size: 12px; line-height: 1.5; color: var(--ink-subtle); text-align: center; }

/* Narrow: the price panel drops below the inputs, so a bar with the total and
   the button rides the bottom — the figure a rep reads out is never a scroll
   away. Hidden on wide screens, where the panel itself stays in view. */
.pc-sticky { display: none; }
@media (max-width: 1100px) {
  .pc-out { position: static; }
  .pc-out .pc-cta { display: none; }
  .pc-sticky {
    display: flex; align-items: center; gap: 14px; position: sticky; bottom: 0; z-index: 5;
    padding: 12px 16px; border-radius: var(--r-lg);
    background: var(--e3-bg); border: 1px solid var(--hairline-strong); box-shadow: var(--shadow-2);
  }
  .pc-sticky__i { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
  .pc-sticky__i b { font: 800 26px/1 var(--mono); white-space: nowrap; font-variant-numeric: tabular-nums; }
  .pc-sticky .pc-cta { width: auto; margin-inline-start: auto; padding: 0 20px; flex: none; }
  .pc-sticky .pc-cta--add { margin-inline-start: auto; padding: 0 14px; gap: 6px; }
  .pc-sticky .pc-cta--add + .pc-cta { margin-inline-start: 0; }
  .pc-sticky .pc-cta--add svg { width: 16px; height: 16px; }
}
@media (max-width: 640px) {
  .pc-sec { padding: 18px 16px 20px; }
  .pc-prod { grid-template-columns: minmax(0, 1fr); }
  .pc-readout { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pc-readout > div:last-child { display: none; }
  .pc-readout > div:nth-child(2) { border-inline-end: 0; }
  .pc-sticky .pc-cta { font-size: 14px; padding: 0 14px; min-height: 48px; }
  .pc-sticky__i b { font-size: 21px; }
}
/* With Add beside Price offer the bar holds three things: the label keeps to
   one line, the total steps down, and Add becomes its + alone. The total is
   never covered — it is the figure the rep reads out. */
/* The narrowest phones: the total takes its own line above the buttons (v4.240: at 320 px "EGP 209,955" ran into Add). */
@media (max-width: 360px) {
  .pc-sticky { flex-wrap: wrap; }
  .pc-sticky .pc-sticky__i { flex: 1 1 100%; }
  .pc-sticky .pc-cta:not(.pc-cta--add) { flex: 1 1 auto; justify-content: center; }
}
@media (max-width: 480px) {
  .pc-sticky { gap: 8px; padding: 10px 12px; }
  .pc-sticky__i { flex: 1 1 auto; }
  .pc-sticky__i .pc-k { line-height: 1.25; }   /* wraps to a second line rather than losing "Delivery" (v4.240) */
  .pc-sticky__i b { font-size: 17px; }
  .pc-sticky__i { min-width: 0; }
  .pc-sticky .pc-cta--add { width: 48px; padding: 0; margin-inline-start: 0; }
  .pc-sticky .pc-cta--add .pc-cta__t { display: none; }
  .pc-sticky .pc-cta { padding: 0 12px; }
}

/* ── Price calculator → Price Offer ───────────────────────────────────────────
   The rep's own percentage, the offer in progress, issued offers, and the two
   sheets (offer details, approval request). */
.pc-pct { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-top: -4px; }
.pc-pct__l { font-size: 12.5px; font-weight: 700; color: var(--ink-muted); }
.pc-pct__in { display: flex; align-items: center; gap: 6px; }
.pc-pct__in .pc-sel { width: 96px; height: 40px; font-family: var(--mono); }
.pc-link {
  border: 0; background: none; padding: 4px 0; cursor: pointer; font: 700 13px/1.25 var(--ui);
  color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px;
}
.pc-link--c { align-self: center; }
.pc-link:focus-visible { outline: 2px solid var(--accent-focus); outline-offset: 2px; border-radius: 4px; }
.pc-appr {
  margin: 0; padding: 12px 14px; border-radius: 10px; font-size: 13px; line-height: 1.5;
  background: var(--accent-wash); border: 1px solid color-mix(in srgb, var(--accent) 44%, transparent); color: var(--ink);
}
.pc-row--total small { font-size: 11px; font-weight: 600; color: var(--ink-subtle); margin-inline-start: 4px; }

.pc-basket { padding: 4px 22px 22px; border-top: 1px solid var(--wash); }
.pc-basket ul, .pc-issued__l, .of-lines { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.pc-basket li, .pc-issued__l li, .of-lines li {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 10px;
  background: var(--wash); border: 1px solid var(--hairline);
}
.pc-basket li > span:first-child, .pc-issued__l li > span:first-child, .of-lines li > span:first-child {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; font-size: 13.5px;
}
.pc-basket li small, .pc-issued__l li small, .of-lines li small { font-size: 12px; color: var(--ink-subtle); }
.pc-basket li > span:nth-child(2), .pc-issued__l li > span:nth-child(2) { font: 700 13px/1.25 var(--mono); white-space: nowrap; }
.pc-x {
  width: 32px; height: 32px; flex: none; border-radius: 8px; border: 1px solid var(--hairline-strong);
  background: var(--e1-bg); color: var(--ink-subtle); font-size: 18px; line-height: 1; cursor: pointer;
}
.pc-x:hover { color: var(--danger); border-color: var(--danger); }
.pc-issued { width: 100%; }
/* .btn is full width everywhere else; in a list row that took the whole row
   and squeezed the name to a word per line. */
.pc-issued__l .pc-open { width: auto; flex: none; min-height: 36px; padding: 0 16px; font-size: 13px; }
.pc-issued__l li > span:first-child b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; unicode-bidi: plaintext; }
.pc-basket__how { margin: 10px 0 0; font-size: 12.5px; line-height: 1.45; color: var(--ink-subtle); }
.pc-basket__how b { color: var(--ink); }
.pc-ghost svg, [data-of-act="more"] svg { width: 16px; height: 16px; flex: none; }

.of-form { display: flex; flex-direction: column; gap: 6px; }
.of-form .label { margin-top: 6px; }
.of-sum { margin-top: 12px; }
.lo-addoffer { min-height: 30px; padding: 0 10px; font-size: 12px; margin-inline-start: 6px; }
.lo-used { margin-inline-start: 6px; font-size: 12px; color: var(--ink-muted); white-space: nowrap; }

/* Live Orders' header for the Smart Advisor: only the way back — the advisor
   carries its own title, as designed. */
.lo-head--bare { display: block; }
.lo-head--bare .lo-head__nav { margin-bottom: 0; }

/* ── Pin a location (new account, account sheet) ───────────────────────────── */
.loc { display: flex; flex-direction: column; gap: 10px; }
.loc__main { gap: 10px; }
.loc__ico svg, .row__pin svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.loc__main .loc__ico { color: var(--accent-ink); display: inline-flex; }
.loc__hint { margin: 0; font-size: 12.5px; color: var(--ink-subtle); line-height: 1.45; }
.loc__ok { margin: 0; display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 12px;
  background: color-mix(in srgb, var(--success) 12%, transparent); border: 1px solid color-mix(in srgb, var(--success) 40%, transparent); }
.loc__ok .loc__ico { color: var(--success); display: inline-flex; flex: none; }
.loc__ok b { display: block; font-size: 14px; color: var(--ink); }
.loc__ok small { display: block; font-size: 12px; color: var(--ink-subtle); font-family: var(--mono); margin-top: 2px; }
.loc__warn { margin: 0; padding: 12px 14px; border-radius: 12px; font-size: 13px; line-height: 1.45; color: var(--ink);
  background: var(--accent-wash); border: 1px solid color-mix(in srgb, var(--accent) 44%, transparent); }
.loc__acts { display: flex; gap: 8px; flex-wrap: wrap; }
.loc__btn { width: auto; flex: 1 1 140px; min-height: 44px; font-size: 14px; }
.loc__line { margin: 0; display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--ink-muted); min-height: 44px; }
.loc__spin { width: 18px; height: 18px; border-radius: 50%; border: 2.5px solid var(--wash-strong); border-top-color: var(--accent); animation: locspin .8s linear infinite; flex: none; }
@keyframes locspin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .loc__spin { animation: none; } }
.row__pin { display: inline-flex; vertical-align: -3px; margin-inline-end: 4px; color: var(--success); }
.row__pin svg { width: 14px; height: 14px; }

/* Settings: settings.css draws the page; the host only gives it room. */
.st-host { min-width: 0; padding-top: 4px; }
.help__i { padding: 12px 0; border-bottom: 1px solid var(--wash); }
.help__i:last-child { border-bottom: 0; }
.help__i b { display: block; font-size: 14.5px; color: var(--ink); }
.help__i p { margin: 4px 0 0; font-size: 13.5px; line-height: 1.5; color: var(--ink-muted); }

/* ── Sales Report: activity this month ── */
.rp-acts__l { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.rp-acts__i { width: 100%; min-height: 92px; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--hairline);
  background: var(--wash); color: var(--ink); text-align: start; cursor: pointer; display: flex; flex-direction: column; gap: 2px;
  font: inherit; transition: border-color .15s, background-color .15s; }
.rp-acts__i:hover { border-color: color-mix(in srgb, var(--accent) 50%, transparent); }
.rp-acts__i:focus-visible { outline: 2px solid var(--accent-focus); outline-offset: 2px; }
.rp-acts__i b { font: 800 26px/1.05 var(--ui); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.rp-acts__i span { font-size: 13px; font-weight: 700; color: var(--ink); }
.rp-acts__i small { font-size: 12px; color: var(--ink-subtle); line-height: 1.35; }

/* ── Equivalents (equivalents.js) ── */
.eq-list { display: flex; flex-direction: column; gap: 12px; }
.eq-card { background: var(--panel, var(--charcoal)); border: 1px solid var(--line); border-radius: 16px; padding: 16px; display: flex; flex-direction: column; gap: 10px; }
.eq-card--none { border-color: color-mix(in srgb, #e2604b 45%, var(--line)); }
.eq-card__h { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.eq-card__t { margin: 0; font-size: 16px; font-weight: 800; color: var(--ink); }
.eq-card__s { margin: 3px 0 0; font-size: 12.5px; color: var(--steel); }
.eq-card__s b { color: var(--ink); }
.eq-card__c { margin: 3px 0 0; font-size: 12px; color: var(--ink-subtle, var(--steel)); }
.eq-lv { flex: none; display: inline-block; padding: 3px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 800; white-space: nowrap; border: 1px solid transparent; }
.eq-lv--exact { background: color-mix(in srgb, #2fb36b 18%, transparent); color: var(--success, #2fb36b); }
.eq-lv--func { background: color-mix(in srgb, #f5a524 18%, transparent); color: var(--accent-ink); }
.eq-lv--partial { background: color-mix(in srgb, #f47b0b 16%, transparent); color: var(--accent-ink); border-color: color-mix(in srgb, #f47b0b 45%, transparent); }
.eq-lv--none { background: color-mix(in srgb, #e2604b 16%, transparent); color: var(--danger, #e2604b); }
.eq-why { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--ink); }
.eq-warn { margin: 0; padding: 8px 10px; border-radius: 10px; background: color-mix(in srgb, #f5a524 12%, transparent); font-size: 12.5px; line-height: 1.45; color: var(--ink); }
.eq-ms { display: flex; flex-direction: column; gap: 6px; }
.eq-m { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 10px; align-items: center; width: 100%; padding: 10px 12px; border-radius: 12px; border: 1px solid var(--line); background: var(--wash); color: var(--ink); text-align: start; cursor: pointer; font: inherit; }
.eq-m:hover { border-color: color-mix(in srgb, var(--accent) 50%, transparent); }
.eq-m__n { font-size: 14px; font-weight: 700; }
.eq-m__n b { color: var(--accent-ink); }
.eq-m__note { grid-column: 1 / -1; font-size: 12.5px; line-height: 1.45; color: var(--steel); }
.eq-pick { margin: 0; font-size: 12.5px; font-weight: 700; color: var(--steel); }
.eq-grades { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 6px; }
.eq-g { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 9px 11px; border-radius: 11px; border: 1px solid var(--line); background: var(--wash); color: var(--ink); cursor: pointer; font: inherit; text-align: start; }
.eq-g:hover { border-color: color-mix(in srgb, var(--accent) 50%, transparent); }
.eq-g__n { font-size: 13.5px; font-weight: 800; display: flex; flex-direction: column; }
.eq-g__n small { font-size: 11.5px; font-weight: 600; color: var(--steel); }
.eq-src { margin: 0; font-size: 11.5px; color: var(--steel); }
.eq-legend { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; font-size: 13px; line-height: 1.45; color: var(--steel); }
.eq-legend .eq-lv { margin-inline-end: 6px; }
.eq-rep { font-size: 13px; line-height: 1.6; color: var(--steel); margin: 0; display: grid; grid-template-columns: max-content 1fr; gap: 6px 12px; }
.eq-rep dt { font-weight: 800; color: var(--ink); white-space: nowrap; }
.eq-rep dd { margin: 0; }
@media (max-width: 520px) {
  .eq-card__h { flex-direction: column; }
}

/* ── Coloured icon tiles (2026-10-09; palette in theme.css) ───────────────── */
.navitem > svg:not(.navitem__chev), .navsub__i svg {
  box-sizing: content-box; background: var(--tile, var(--tile-grey));
  color: var(--tile-ink); stroke: var(--tile-ink);
}
.navitem > svg:not(.navitem__chev) { width: 16px; height: 16px; padding: 5px; border-radius: 8px; }
.navsub__i svg { width: 14px; height: 14px; padding: 4px; border-radius: 7px; }
.navitem[data-tab="home"]      { --tile: var(--tile-orange); }
.navitem[data-tab="orders"]    { --tile: var(--tile-green); }
.navitem[data-tab="catalogue"] { --tile: var(--tile-blue); }
.navitem[data-tab="equiv"]     { --tile: var(--tile-purple); }
.navitem[data-tab="accounts"]  { --tile: var(--tile-teal); }
.navitem[data-tab="requests"]  { --tile: var(--tile-indigo); }
.navitem[data-tab="more"]      { --tile: var(--tile-grey); }
.navsub__i[data-lo="report"]   { --tile: var(--tile-blue); }
.navsub__i[data-lo="live"]     { --tile: var(--tile-green); }
.navsub__i[data-lo="calc"]     { --tile: var(--tile-orange); }
.navsub__i[data-lo="advisor"]  { --tile: var(--tile-purple); }
.navsub__i[data-lo="offers"]   { --tile: var(--tile-amber); }
.navsub__i[data-lo="products"] { --tile: var(--tile-red); }
.navsub__i[data-lo="stock"]    { --tile: var(--tile-teal); }

/* ── Import accounts from Excel (2026-10-09) ──────────────────────────────── */
.imp__p { margin: 0 0 10px; font-size: 13.5px; line-height: 1.5; color: var(--ink-subtle); }
.imp__pick { position: relative; width: 100%; margin-top: 6px; cursor: pointer; }
.imp__pick:focus-within { outline: 2px solid var(--accent-focus); outline-offset: 2px; }
.imp__tpl { width: 100%; margin-top: 10px; }
.imp__err { color: var(--danger); }
.imp__map { display: flex; flex-direction: column; gap: 8px; margin: 6px 0 4px; max-height: 46vh; overflow-y: auto; }
.imp__col { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; align-items: center;
            padding: 8px 10px; border: 1px solid var(--hairline); border-radius: 12px; }
.imp__col.is-key { border-color: var(--accent-ink); }
.imp__h { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.imp__h b { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.imp__h small { font-size: 12px; color: var(--ink-subtle); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.imp__sel { min-height: 40px; font-size: 13px; }
.imp__sum { margin-top: 12px; padding: 12px 14px; border-radius: 12px; background: var(--wash); display: flex; flex-direction: column; gap: 6px; }
.imp__sum p { margin: 0; font-size: 13.5px; line-height: 1.45; }
.imp__warn { color: var(--accent-ink); }
@media (max-width: 420px) { .imp__col { grid-template-columns: 1fr; gap: 6px; } }

/* ── The rep's sections, organised around the work (2026-10-12) ─────────────
   Home · Orders · Products · Accounts, then More. On a laptop the four carry a
   line saying what is in them, Products shows its own two (Equivalents, Stock)
   and More is a list with chevrons. On a phone the bar is those four plus More,
   which opens the lists over the bar (#loPop). */
.navitem__s, .rail__sec, .rail__tag { display: none; }
.navsub__chev { display: flex; margin-inline-start: auto; flex: none; opacity: .55; }
.navsub__chev svg { width: 14px !important; height: 14px !important; padding: 0 !important; background: none !important;
  stroke: currentColor !important; color: var(--ink-subtle); fill: none; stroke-width: 2.2; transition: transform var(--dur-fast) var(--ease); }
.navsub__i em + .navsub__chev { margin-inline-start: 6px; }
.navsub__i em { margin-inline-start: auto; }
[dir="rtl"] .navsub__chev svg { transform: scaleX(-1); }
.navsub__h { margin: 8px 12px 2px; font: 700 11px/1.2 var(--ui); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-subtle); }
.navsub__grp { display: none; flex-direction: column; gap: 2px; margin-inline-start: 22px; padding-inline-start: 10px; border-inline-start: 1px solid var(--hairline-strong); }
.navsub__grp.is-open { display: flex; }
.navsub__i--tools[aria-expanded="true"] .navsub__chev svg { transform: rotate(90deg); }
[dir="rtl"] .navsub__i--tools[aria-expanded="true"] .navsub__chev svg { transform: scaleX(-1) rotate(90deg); }
.navsub__i--tools.is-in { color: var(--ink); font-weight: 600; }
/* Their icon tiles (palette in theme.css), one colour per kind of work. */
.navitem[data-more]                 { --tile: var(--tile-grey); }
.navsub__i[data-tab="equiv"]        { --tile: var(--tile-purple); }
.navsub__i[data-tab="requests"]     { --tile: var(--tile-indigo); }
.navsub__i[data-tab="more"]         { --tile: var(--tile-grey); }
.navsub__i[data-sample-open]        { --tile: var(--tile-pink); }
.navsub__i--tools                   { --tile: var(--tile-amber); }

@media (max-width: 1023px) {
  #loSub, #prodSub { display: none !important; }        /* the phone has them in More */
  .navsub--pop.is-open { max-height: min(70vh, 560px); overflow-y: auto; }
}
@media (min-width: 1024px) {
  .navitem--more { display: none !important; }
  .rail__tag { display: block; margin-top: 4px; font-size: 11px; font-weight: 600; color: var(--steel); letter-spacing: .02em; }
  .rail__sec { display: block; margin: 16px 14px 6px; font: 700 11px/1.2 var(--ui); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-subtle); }
  /* The four: icon, then name over what is in it. */
  #nav > .navitem:not(.navitem--more) {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "ic t b" "ic s b";
    align-items: center; column-gap: 12px; row-gap: 2px; padding: 10px 14px;
  }
  #nav > .navitem > svg { grid-area: ic; }
  #nav > .navitem > span { grid-area: t; line-height: 1.2; }
  #nav > .navitem > .navitem__s { display: block; grid-area: s; font-size: 12px; font-weight: 500; line-height: 1.3; color: var(--ink-subtle); white-space: normal; }
  #nav > .navitem > .navitem__badge { grid-area: b; }
  /* More: a plain list, not the indented sub-list. */
  #loSub.navsub--more { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; border: 0; }
  #prodSub { display: flex; }
}

/* ── Quotations (2026-10-12, layout from the reference; the app's own colours) ─ */
.qt { display: flex; flex-direction: column; gap: 14px; max-width: 760px; }
.qt-head { display: flex; flex-direction: column; gap: 4px; }
.qt-eyebrow { margin: 0; font: 600 12px/1.3 var(--ui); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-subtle); }
.qt-titlerow { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.qt-titlerow h1 { margin: 0; font-size: 28px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); }
.qt-sub { margin: 0; font-size: 14.5px; color: var(--ink-subtle); }
.qt-iconbtn { width: 44px; height: 44px; display: grid; place-items: center; border: 0; border-radius: 12px; background: transparent; color: var(--ink); cursor: pointer; }
.qt-iconbtn:hover { background: var(--wash); }
.qt svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.qt-create { display: flex; align-items: center; gap: 14px; width: 100%; padding: 18px 18px; border: 0; border-radius: var(--r-lg, 16px);
  background: var(--accent); color: var(--on-accent); text-align: start; cursor: pointer; box-shadow: var(--shadow-1);
  transition: transform var(--dur-fast) var(--ease), filter var(--dur-fast) var(--ease); }
.qt-create:hover { filter: brightness(1.05); }
.qt-create:active { transform: scale(var(--press)); }
.qt-create__ic { width: 40px; height: 40px; display: grid; place-items: center; border-radius: 12px; border: 2px solid currentColor; flex: none; }
.qt-create__t { display: flex; flex-direction: column; gap: 3px; flex: 1 1 auto; min-width: 0; }
.qt-create__t b { font-size: 18px; font-weight: 800; }
.qt-create__t small { font-size: 14px; font-weight: 500; opacity: .85; }
.qt-hist { padding: 16px 18px; border-radius: var(--r-lg, 16px); background: var(--e1-bg); border: 1px solid var(--e1-border); box-shadow: var(--shadow-1); }
.qt-kick { margin: 0 0 6px; font: 600 12px/1.3 var(--ui); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-subtle); }
.qt-hist h2 { margin: 0 0 4px; font-size: 22px; font-weight: 800; color: var(--ink); }
.qt-hist p:last-child { margin: 0; font-size: 14px; color: var(--ink-subtle); }
.qt-search { display: flex; align-items: center; gap: 10px; min-height: 50px; padding: 0 14px; border-radius: 14px; background: var(--e1-bg); border: 1px solid var(--e1-border); color: var(--ink-subtle); cursor: text; }
.qt-search input { flex: 1 1 auto; min-width: 0; border: 0; background: transparent; color: var(--ink); font: 500 15px var(--ui); outline: none; }
.qt-search:focus-within { border-color: var(--accent-ink); box-shadow: 0 0 0 3px var(--accent-focus); }
.qt-tune { opacity: .8; }
.qt-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.qt-chip { min-height: 40px; padding: 0 18px; border-radius: 999px; border: 1px solid var(--e1-border); background: var(--e1-bg); color: var(--ink); font: 600 14px var(--ui); cursor: pointer; }
.qt-chip.is-on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.qt-list { display: flex; flex-direction: column; gap: 12px; }
.qt-card { border-radius: var(--r-lg, 16px); background: var(--e1-bg); border: 1px solid var(--e1-border); box-shadow: var(--shadow-1); overflow: hidden; }
.qt-card__top { display: flex; align-items: flex-start; gap: 14px; padding: 16px 18px 14px; }
.qt-ic { width: 46px; height: 46px; display: grid; place-items: center; border-radius: 12px; background: var(--wash-strong); color: var(--ink); flex: none; }
.qt-card__main { display: flex; flex-direction: column; gap: 4px; flex: 1 1 auto; min-width: 0; }
.qt-no { font: 700 18px/1.2 var(--mono); color: var(--ink); letter-spacing: -.01em; overflow-wrap: anywhere; }
.qt-cust { font-size: 15px; color: var(--ink); }
.qt-date { font-size: 13px; color: var(--ink-subtle); }
.qt-badge { flex: none; padding: 4px 12px; border-radius: 999px; font: 700 12.5px var(--ui); color: var(--success);
  background: color-mix(in srgb, var(--success) 14%, transparent); }
.qt-card__foot { display: flex; align-items: center; gap: 4px; padding: 8px 10px 8px 18px; border-top: 1px solid var(--hairline); }
.qt-pdf { display: inline-flex; align-items: center; gap: 8px; flex: 1 1 auto; font-size: 14px; font-weight: 600; color: var(--ink); }
.qt-pdf svg { color: var(--success); }
.qt-act { width: 44px; height: 44px; display: grid; place-items: center; border: 0; border-radius: 12px; background: transparent; color: var(--accent-ink); cursor: pointer; }
.qt-act:hover { background: var(--wash); }
.qt-act .qt-chev { color: var(--ink-subtle); }
.qt-empty { margin: 0; padding: 18px; border-radius: 14px; border: 1px dashed var(--hairline-strong); color: var(--ink-subtle); font-size: 14px; line-height: 1.5; }
[dir="rtl"] .qt-chev { transform: scaleX(-1); }
.qt-amt { white-space: nowrap; }

/* ── Date fields (date-field.js, v4.134) ─────────────────────────────────────
   The native date box keeps its picker; its own text (the phone's format,
   often mm/dd/yyyy) is hidden and "12 Oct 2026" is drawn over it. */
.df { position: relative; display: block; min-width: 0; }
.df > .df-input { width: 100%; color: transparent !important; caret-color: transparent; }
.df > .df-input::-webkit-datetime-edit { color: transparent; }
.df-label {
  position: absolute; top: 0; bottom: 0; left: 0; right: 40px;   /* physical: the picker icon is on the right in both directions */
  display: flex; align-items: center; pointer-events: none;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.df-label.is-empty { opacity: .6; }
[dir="rtl"] .df-label { padding-left: 8px !important; padding-right: 8px; }   /* starts on the right, beside the icon */

/* ── Home opens on today (v4.134) ─────────────────────────────────────────── */
.home-today {
  display: flex; flex-direction: column; gap: 8px; padding: 14px 16px;
  border-radius: var(--r-lg, 16px); background: var(--e1-bg); border: 1px solid var(--hairline);
}
.today__k { margin: 0; font-size: 12px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--accent-ink); }
.today__row { display: flex; flex-wrap: wrap; gap: 8px; }
.today__c {
  display: inline-flex; align-items: baseline; gap: 6px; min-height: 40px; padding: 8px 14px; border-radius: 99px;
  background: var(--e2-bg); border: 1px solid var(--hairline-strong); color: var(--ink); font-size: 14px; font-weight: 600;
}
.today__c b { font-size: 16px; font-weight: 800; }
.today__c.is-late { color: var(--danger); border-color: var(--danger-wash); background: var(--danger-wash); }
.today__c.is-news { color: var(--accent-ink); border-color: var(--accent-wash); background: var(--accent-wash); }
.today__none { margin: 0; font-size: 14px; color: var(--ink-subtle); }

/* The fold: map cards and recent activity, closed until opened. */
.home-more { display: flex; flex-direction: column; gap: 16px; }
.home-more > .dash, .home-more > .panel { margin-top: 16px; }
.home-more__h {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; cursor: pointer; list-style: none;
  min-height: 52px; padding: 0 18px; border-radius: var(--r-lg, 16px);
  background: var(--e1-bg); border: 1px solid var(--hairline); color: var(--ink); font-size: 15px; font-weight: 700;
}
.home-more__h::-webkit-details-marker { display: none; }
.home-more__h svg { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform .2s ease; }
.home-more[open] .home-more__h svg { transform: rotate(180deg); }

/* New order: a button floating above the bottom bar, on Home. */
.fab {
  position: fixed; z-index: 40; inset-inline-end: 16px; bottom: calc(var(--safe-b) + 84px);
  display: inline-flex; align-items: center; gap: 8px; min-height: 52px; padding: 0 22px 0 18px; border-radius: 99px;
  background: var(--accent); color: var(--on-accent); font-size: 15px; font-weight: 800; border: 0; cursor: pointer;
  box-shadow: 0 12px 30px rgba(0, 0, 0, .35), 0 0 0 1px rgba(255, 255, 255, .06) inset;
}
.fab svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; }
.fab:active { transform: scale(.97); }
@media (min-width: 1024px) { .fab { bottom: calc(var(--safe-b) + 28px); inset-inline-end: 28px; } }
/* Room under the last card, so the button never sits on it for good. */
#main:has(.fab) { padding-bottom: calc(var(--safe-b) + 150px); }
/* The toast rises above the floating button on Home. */
body:has(.fab) .toast { bottom: calc(72px + var(--safe-b) + 86px); }
@media (min-width: 1024px) { body:has(.fab) .toast { bottom: calc(var(--safe-b) + 96px); } }

/* ── The phone bar and its More menu, as the manager's (v4.136) ──────────────
   Full width along the bottom edge (it was a floating capsule), the chosen
   place in a lit box, and More a compact menu anchored over the bar's right
   end: plain icons, one row per place, Sign out last. */
@media (max-width: 1023px) {
  .rail {
    margin: 0; border-radius: 0; border: 0; border-top: 1px solid var(--hairline);
    background: var(--e1-bg); backdrop-filter: none; -webkit-backdrop-filter: none;
    box-shadow: 0 -10px 30px var(--shadow-color); overflow: visible;
    padding: 6px calc(var(--safe-r) + 6px) calc(var(--safe-b) + 6px) calc(var(--safe-l) + 6px);
  }
  .rail__nav { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 2px; }
  .rail__nav > .navitem {
    position: relative; min-height: 56px; padding: 4px 2px; border-radius: var(--r-md, 10px);
    font-size: 11px; font-weight: 600; gap: 3px; min-width: 0;
  }
  .rail__nav > .navitem > span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .rail__nav > .navitem.is-active { background: var(--accent-wash); color: var(--accent-ink); box-shadow: var(--glow-ring); }
  .rail__nav > .navitem .navitem__badge { position: absolute; top: 3px; inset-inline-start: calc(50% + 4px); margin: 0; }

  .navsub--pop.is-open {
    inset-inline: auto calc(var(--safe-r) + 10px); width: auto; min-width: 240px; max-width: calc(100vw - 20px);
    bottom: calc(var(--safe-b) + 78px); padding: 6px; gap: 2px; border-radius: 14px;
    /* e2 is translucent in the light theme: laid over the solid canvas, so the page never shows through. */
    background: linear-gradient(var(--e2-bg), var(--e2-bg)), var(--canvas); border: 1px solid var(--hairline-strong); box-shadow: 0 18px 50px var(--shadow-color);
    animation: menuIn .16s var(--ease, ease) both;
  }
  #loPop .navsub__i { min-height: 48px; padding: 0 14px; gap: 12px; color: var(--ink); font-size: 15px; font-weight: 600; border-radius: 10px; }
  #loPop .navsub__i:hover, #loPop .navsub__i:focus-visible { background: var(--e3-bg); }
  #loPop .navsub__i.is-on { background: var(--accent-wash); color: var(--accent-ink); }
  #loPop .navsub__i > svg { width: 19px !important; height: 19px !important; padding: 0 !important; background: none !important;
                            border-radius: 0 !important; stroke: currentColor !important; color: inherit !important; }
  #loPop .navsub__chev, #loPop .navsub__h { display: none !important; }
  #loPop .navsub__i em { font-size: 12px; color: var(--accent-ink); }
  #loPop .navsub__i--out { color: var(--danger); border-top: 1px solid var(--hairline); border-radius: 0 0 10px 10px; margin-top: 2px; }
}
@keyframes menuIn { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .navsub--pop.is-open { animation: none; } }

/* Customize Home (v4.140): a card whose partner is left out takes the row. */
.dash.dash--one { grid-template-columns: minmax(0, 1fr) !important; }
#homeWidgets[hidden] { display: none !important; }

/* Product rows show the pack, not initials (v4.143): a soft tile, the picture
   contained, so the three silhouettes (pail, 20 L jerrycan, barrel) sit on one
   baseline. Accounts keep their initials. */
.row--pack { grid-template-columns: 54px minmax(0, 1fr) auto; }
.row__pack {
  width: 54px; height: 58px; display: grid; place-items: center; border-radius: var(--r-md);
  background: var(--wash);
}
.row__pack img {
  display: block; height: 46px; width: auto; max-width: 42px; object-fit: contain;
  filter: drop-shadow(0 3px 5px rgba(0, 0, 0, .35));
}
:root[data-scheme="light"] .row__pack img { filter: drop-shadow(0 3px 4px rgba(16, 24, 40, .22)); }

/* On a phone the header holds the avatar, the name, this pill, the bell, Customize and
   Refresh. A real name ("Shabaan Eldewedni") was cut to "Shabaa…", so when all is well
   the pill is only its dot; any other state keeps its words. */
@media (max-width: 480px) {
  .sync.is-quiet .sync__txt { display: none; }
  .sync.is-quiet { padding-inline: 10px; }
}
/* The narrowest phones (320-374 px): the avatar, the dot and three 48 px buttons left the name about 30 px, one
   letter per line (v4.240, the layout audit). Here the all-is-well dot goes (any other state still shows its words),
   the buttons are 40 px (still well above the 24 px minimum) and the gaps tighten, so the name gets ~100 px. */
@media (max-width: 374px) {
  .sync.is-quiet { display: none; }
  .topbar { gap: 6px; }
  .topbar .iconbtn { width: 40px; height: 40px; }
}

/* ══ ORDERS: search, ageing, a tighter table, phone cards (v4.152) ═══════════ */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.ord-bar { display: flex; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.ord-search { flex: 1 1 240px; min-width: 0; display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 0 12px;
  border-radius: 12px; background: var(--wash); border: 1px solid var(--line); }
.ord-search:focus-within { border-color: var(--accent-ink); }
.ord-search svg { width: 17px; height: 17px; flex: none; fill: none; stroke: var(--steel); stroke-width: 2; stroke-linecap: round; }
.ord-search input { flex: 1; min-width: 0; border: 0; outline: 0; background: none; color: var(--white); font: 500 14px var(--ui); }
.ord-sort select { min-height: 40px; padding: 0 12px; border-radius: 12px; background: var(--wash); border: 1px solid var(--line);
  color: var(--white); font: 600 13px var(--ui); }
.ord-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.ord-chip { min-height: 34px; padding: 0 13px; border-radius: 99px; border: 1px solid var(--line); background: none;
  color: var(--steel); font: 700 12.5px var(--ui); cursor: pointer; }
.ord-chip:hover { color: var(--white); }
.ord-chip.is-on { background: var(--accent-wash); border-color: var(--accent-ink); color: var(--accent-ink); }
.ord-count { margin: 0 0 6px; font-size: 12.5px; color: var(--steel); }
.ord-clear { background: none; border: 0; padding: 0; color: var(--accent-ink); font: 700 12.5px var(--ui); cursor: pointer; text-decoration: underline; }

/* The table: less padding, numbers on the right, the whole row opens the order. */
.lo-tbl--ord th, .lo-tbl--ord td { padding: 7px 10px; }
.lo-tbl--ord td:first-child { min-width: 150px; max-width: 280px; }
.lo-tbl--ord .ord-prod { white-space: normal; min-width: 130px; max-width: 220px; color: var(--ink-subtle, var(--steel)); }
.lo-tbl--ord tbody tr { cursor: pointer; }
.lo-tbl--ord tbody tr:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: -2px; }
.ord-go { text-align: end; white-space: nowrap; }
.ord-go .lo-addoffer { margin-inline-end: 8px; }
.ord-chev { color: var(--steel); font-size: 20px; line-height: 1; vertical-align: middle; }
.lo-tbl--ord tbody tr:hover .ord-chev { color: var(--accent-ink); }

/* Ageing: four steps, red only for the last, with a marker on the row. */
.ord-age { display: inline-flex; align-items: baseline; gap: 2px; padding: 2px 9px; border-radius: 99px; font-weight: 700;
  font-variant-numeric: tabular-nums; border: 1px solid transparent; }
.ord-age small { font-size: .78em; }
:root[data-scheme="light"] .ord-age--3, :root[data-scheme="light"] .ord-next--hot { color: #9b1c26; }
:root[data-scheme="light"] .ord-age__dot { background: #9b1c26; }
.ord-age--0 { color: var(--white); }
.ord-age--1 { color: var(--accent-ink); }
.ord-age--2 { color: var(--accent-ink); background: var(--accent-wash); border-color: var(--accent-focus); font-weight: 800; }
.ord-age--3 { color: var(--danger); background: var(--danger-wash); border-color: var(--danger); font-weight: 800; font-size: 1.05em; align-items: center; }
.ord-age__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--danger); margin-inline-end: 5px; align-self: center; }
.ord-row--3 td:first-child, .ord-card--3 { box-shadow: inset 3px 0 0 var(--danger); }
.ord-row--2 td:first-child, .ord-card--2 { box-shadow: inset 3px 0 0 var(--accent-ink); }
.ord-next { font-size: 12.5px; font-weight: 700; }
.ord-next--calm { color: var(--steel); }
.ord-next--warm { color: var(--accent-ink); }
.ord-next--hot  { color: var(--danger); }
.ord-next--good { color: var(--success, #43E6A7); }

/* Phone: cards instead of a squeezed table. */
.ord-cards { display: none; }
@media (max-width: 620px) {
  .ord-wrap { display: none; }
  .ord-cards { display: flex; flex-direction: column; gap: 8px; }
  .ord-card { padding: 11px 13px; border-radius: 14px; background: var(--wash); border: 1px solid var(--line); cursor: pointer; }
  .ord-card:focus-visible { outline: 2px solid var(--accent-ink); }
  .ord-card__top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
  .ord-card__client { min-width: 0; font-size: 15px; font-weight: 700; color: var(--white); overflow-wrap: anywhere; }   /* v4.240 layout audit: wraps, never cut */
  .ord-card__sub { margin: 3px 0 0; font-size: 12.5px; color: var(--steel); }
  .ord-card__mid { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; }
  .ord-card__val { font: 700 15px var(--mono); font-variant-numeric: tabular-nums; color: var(--white); }
  .ord-card__val small { font-size: 11px; color: var(--steel); }
  .ord-card__date { font-size: 12.5px; color: var(--steel); }
  .ord-card__act { margin-top: 8px; }
  .ord-card__act .btn { width: 100%; }
}

/* The order's own page. */
.ord-d__status { display: flex; align-items: center; gap: 8px; margin: 6px 0 12px; }
.se { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 12px 0 4px; }
.se__f { display: flex; flex-direction: column; gap: 4px; }
.se__f span { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--steel); }
.se__f .input { width: 100%; min-height: 44px; }
@media (max-width: 420px) { .se { grid-template-columns: 1fr; } }
.ord-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 14px; }
.ord-fact { display: flex; flex-direction: column; gap: 1px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.ord-fact span { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--steel); }
.ord-fact b { font-size: 14px; color: var(--white); overflow-wrap: anywhere; }
.ord-next-box { margin-top: 16px; padding: 12px 14px; border-radius: 12px; background: var(--wash); border-inline-start: 3px solid var(--line); }
.ord-next-box--warm { border-color: var(--accent-ink); background: var(--accent-wash); }
.ord-next-box--hot { border-color: var(--danger); background: var(--danger-wash); }
.ord-next-box--good { border-color: var(--success, #43E6A7); }
.ord-next-box .label { margin: 0 0 4px; }
.ord-next-box__t { margin: 0; font-size: 14px; line-height: 1.5; color: var(--white); }
.ord-next-box__s { margin: 6px 0 0; font-size: 12.5px; color: var(--steel); }
/* Orders' three figures: no "no prior month" tag (there is no prior month to
   compare), and on a phone one row, so the list starts on the first screen. */
.lo__kpis--3 .lo-kpi__foot { display: none; }
@media (max-width: 760px) {
  .lo__kpis--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .lo__kpis--3 .lo-kpi { padding: 10px 10px 12px; min-width: 0; }
  .lo__kpis--3 .lo-kpi__ico { display: none; }
  .lo__kpis--3 .lo-kpi__top h2 { font-size: 11px; line-height: 1.25; letter-spacing: .02em; }
  .lo__kpis--3 .lo-kpi__v { font-size: 20px; }
  .lo__kpis--3 .lo-kpi__v small { font-size: 10.5px; display: block; margin-left: 0; }
}
@media (max-width: 760px) {
  .lo__kpis--3 .lo-kpi { min-height: 0; height: auto; align-self: start; }
  .lo__kpis--3 .lo-kpi__top h2 { white-space: normal; }
  .ord-search { flex: 1 1 150px; }
  .ord-sort { flex: 0 0 auto; }
  .ord-sort select { max-width: 140px; }
}

/* Account edits: the held-changes bar and the in-app question (v4.166). */
.acc-dirty { margin: 14px 0 0; padding: 9px 12px; border-radius: 10px; background: var(--accent-wash, rgba(247,161,26,.14)); color: var(--accent-ink, #f7a11a); font-size: 13.5px; font-weight: 700; }
.acd { position: fixed; inset: 0; z-index: 3200; display: flex; align-items: center; justify-content: center; padding: 20px; background: rgba(0,0,0,.6); }
.acd__p { width: min(420px, 100%); max-height: 86vh; overflow-y: auto; padding: 20px; border-radius: 20px; background: var(--e2-bg, #1f2124); border: 1px solid var(--hairline-strong, rgba(255,255,255,.18)); color: var(--ink, #fff); box-shadow: 0 30px 80px rgba(0,0,0,.5); }
.acd__p h2 { margin: 0; font-size: 19px; font-weight: 800; }
.acd__sub { margin: 4px 0 0; font-size: 14px; color: var(--ink-subtle, #9aa3ad); }
.acd__t { margin: 12px 0 0; font-size: 14.5px; line-height: 1.5; color: var(--ink-subtle, #b9c0c7); }
/* "Price offer to make" (v4.244): the standing reminder on Home after a manager approves a request. */
.oa { margin: 0 0 14px; padding: 14px 16px; border-radius: 16px; background: var(--e1-bg, rgba(255,255,255,.04)); border: 1px solid var(--accent, #F7A11A); display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.oa__h { margin: 0; font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-ink, #F7A11A); }
.oa__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 14px; min-width: 0; }
.oa__t { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 200px; }
.oa__t b { font-size: 15.5px; font-weight: 800; overflow-wrap: anywhere; }
.oa__t small { font-size: 13px; color: var(--ink-subtle, #a6acb5); overflow-wrap: anywhere; }
.oa__b { display: flex; align-items: center; gap: 4px 6px; flex: none; }
.oa .oa__go { width: auto; min-height: 44px; padding: 0 18px; flex: none; display: inline-flex; align-items: center; justify-content: center; }
.oa__no { min-height: 44px; padding: 0 12px; border: 0; background: none; color: var(--ink-subtle, #a6acb5); font: inherit; font-size: 14px; font-weight: 700; cursor: pointer; border-radius: 10px; }
.oa__no:hover { color: var(--ink, #fff); text-decoration: underline; text-underline-offset: 3px; }
.oa__no:focus-visible { outline: 2px solid var(--accent, #F7A11A); outline-offset: 2px; }
.oa__more { margin: 0; font-size: 13px; color: var(--ink-subtle, #a6acb5); }
/* "Also delete its sales" (v4.241): a real tick box, the whole line is the target. */
.acd__chk { display: flex; gap: 12px; align-items: flex-start; margin: 14px 0 0; padding: 12px; border-radius: 12px; background: var(--wash, rgba(255,255,255,.05)); font-size: 14.5px; line-height: 1.45; cursor: pointer; }
.acd__chk input { width: 22px; height: 22px; flex: none; margin: 0; accent-color: var(--accent, #F7A11A); }
.btn--danger-o { color: var(--danger, #E5645A); border-color: currentColor; }
.acd__l { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.acd__l li { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: 12px; background: var(--wash, rgba(255,255,255,.05)); }
.acd__l li span { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-subtle, #9aa3ad); }
.acd__l li b { font-size: 15px; }
.acd__l li i { font-style: normal; color: var(--accent-ink, #f7a11a); }
.acd__acts { display: flex; flex-direction: column; gap: 8px; margin-top: 18px; }
.acd__acts .btn { width: 100%; }


/* ── Follow-up reminders in the bell (v4.174) ─────────────────────────────── */
.bell__i.is-remind .bell__ico { background: rgba(247,161,26,.18); color: #f7a11a; }
.bell__i.is-urgent .bell__ico { background: rgba(226,96,75,.2); color: #ff8b78; }
.bell__i.is-urgent { box-shadow: inset 3px 0 0 #e2604b; }
.bell__i.is-read { opacity: .72; }
.bell__h--sub { margin-top: 12px; }
.bell__all--read { margin-bottom: 6px; }
/* An urgent reminder nobody has looked at yet: the bell glows three times, then
   stays still. Opening the bell (or the follow-up) stops it for good. */
.bell__btn.is-urgent { animation: bellGlow 1.4s ease-in-out 3; }
@keyframes bellGlow { 0%,100% { box-shadow: 0 0 0 0 rgba(226,96,75,0); } 50% { box-shadow: 0 0 0 6px rgba(226,96,75,.35); } }
@media (prefers-reduced-motion: reduce) { .bell__btn.is-urgent { animation: none; box-shadow: 0 0 0 2px #e2604b; } }
.fu-page { padding: 0 0 24px; }


/* ── Notification centre rows (v4.175) ────────────────────────────────────── */
.bell__row { display: flex; align-items: flex-start; gap: 2px; }
.bell__row .bell__i { flex: 1; min-width: 0; }
.bell__x { flex: none; width: 36px; height: 36px; margin-top: 4px; border: 0; border-radius: 10px; background: transparent; color: var(--ink-subtle); font-size: 20px; line-height: 1; cursor: pointer; }
.bell__x:hover { background: var(--wash); color: inherit; }
.bell__note { margin: 0 8px 8px; padding: 8px 10px; border-radius: 8px; background: var(--wash); font-size: 12.5px; color: var(--ink-subtle); line-height: 1.4; }
.bell__i.is-info .bell__ico { background: rgba(143,154,163,.2); color: #aab3bb; }

/* ── The iPhone keyboard (viewport-fit.js, 2026-10-16) ───────────────────────
   iOS pans the page instead of shrinking it, which put the top bar out of sight,
   floated the bottom bar and the New order button over the form and left the
   focused field under the clock. While a field is being typed in, the shell is
   as tall as what can be seen, the floating bars step aside, and a focused
   field is scrolled to a spot below the clock, not to the very top edge. */
html.kb-open .app { height: var(--vvh, 100%); }
html.kb-open .rail, html.kb-open .fab { display: none !important; }
@media (min-width: 1024px) { html.kb-open .rail { display: flex !important; } html.kb-open .app { height: 100%; } }
input, textarea, select { scroll-margin-top: calc(var(--safe-t, 0px) + 96px); scroll-margin-bottom: 24px; }
