/* ==========================================================================
   Demes B2B Console - design system
   Shared by www/login.html, www/manager.html and www/agent.html.

   Deliberately its own visual language, separate from the marketing site's
   Tailwind theme: this is an internal operations tool used all day, so it
   optimises for density, scan-ability and calm rather than for landing-page
   impact. Brand red stays the single accent, used sparingly (primary action,
   active nav, focus) so it still means "this is the thing to click".

   Structure
     1.  Fonts
     2.  Tokens
     3.  Base / reset
     4.  App shell (sidebar, topbar, content)
     5.  Page furniture (headers, toolbars, sections)
     6.  Surfaces (cards, stats, panels)
     7.  Data display (tables, badges, key-value, empty, skeleton)
     8.  Controls (buttons, forms, modal, collapsible)
     9.  Feedback (alerts, toasts, loading)
     10. Order console (agent order builder, cart, filters, review)
     10b. Order detail (admin review screen)
     11. Login
     12. Utilities
     13. Motion & print
   ========================================================================== */

/* 1. Fonts ---------------------------------------------------------------- */

/* Vazirmatn is the Persian UI face the whole console is set in. Only the
   five weights actually used are pulled in, to keep the request budget
   small; `swap` means a slow/blocked CDN degrades to Tahoma instead of
   blanking the page. */
@font-face {
  font-family: Vazirmatn;
  src: url('https://cdn.jsdelivr.net/npm/vazirmatn@33.0.3/fonts/webfonts/Vazirmatn-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: Vazirmatn;
  src: url('https://cdn.jsdelivr.net/npm/vazirmatn@33.0.3/fonts/webfonts/Vazirmatn-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: Vazirmatn;
  src: url('https://cdn.jsdelivr.net/npm/vazirmatn@33.0.3/fonts/webfonts/Vazirmatn-SemiBold.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: Vazirmatn;
  src: url('https://cdn.jsdelivr.net/npm/vazirmatn@33.0.3/fonts/webfonts/Vazirmatn-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: Vazirmatn;
  src: url('https://cdn.jsdelivr.net/npm/vazirmatn@33.0.3/fonts/webfonts/Vazirmatn-ExtraBold.woff2') format('woff2');
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

/* 2. Tokens --------------------------------------------------------------- */

:root {
  /* Neutrals - a single cool-grey ramp used for every surface, border and
     text colour, so nothing in the UI is an ad-hoc grey. */
  --n-0: #ffffff;
  --n-25: #fbfcfd;
  --n-50: #f6f8fa;
  --n-100: #eef1f5;
  --n-150: #e4e8ee;
  --n-200: #d8dee7;
  --n-300: #b8c1ce;
  --n-400: #8e99a9;
  --n-500: #6b7788;
  --n-600: #515c6b;
  --n-700: #3c4553;
  --n-800: #262e3a;
  --n-900: #161d27;
  --n-950: #0c111a;

  /* Brand - Demes red. Used for the primary action, the active nav item and
     focus rings only; everything else stays neutral. */
  --brand-50: #fff1f1;
  --brand-100: #ffe0e1;
  --brand-200: #ffc6c8;
  --brand-300: #ff9b9e;
  --brand-400: #fa6165;
  --brand-500: #ed1c24;
  --brand-600: #d21017;
  --brand-700: #b00d13;
  --brand-800: #8c0f14;
  --brand-900: #741317;

  /* Semantic - each has a tint, a border and a readable text tone so
     status surfaces never rely on colour alone at low contrast. */
  --ok-50: #ecfdf3;
  --ok-100: #d1fadf;
  --ok-200: #a6f0c2;
  --ok-600: #067647;
  --ok-700: #05603a;

  --warn-50: #fffaeb;
  --warn-100: #fef0c7;
  --warn-200: #fedf89;
  --warn-600: #b54708;
  --warn-700: #93370d;

  --danger-50: #fef3f2;
  --danger-100: #fee4e2;
  --danger-200: #fecdca;
  --danger-600: #d92d20;
  --danger-700: #b42318;

  --info-50: #eff6ff;
  --info-100: #dbeafe;
  --info-200: #bfdbfe;
  --info-600: #1d4ed8;
  --info-700: #1e40af;

  /* Surfaces */
  --bg-app: #f4f6f9;
  --bg-surface: var(--n-0);
  --bg-subtle: var(--n-50);
  --bg-sunken: var(--n-100);
  --border: var(--n-150);
  --border-strong: var(--n-200);

  /* Sidebar palette - deep navy-black, its own scale so the shell reads as
     chrome rather than as another card. */
  --nav-bg: #0d1420;
  --nav-bg-soft: #141c2b;
  --nav-border: rgba(255, 255, 255, 0.07);
  --nav-text: #9aa6b8;
  --nav-text-strong: #f1f4f9;

  /* Text */
  --text: var(--n-900);
  --text-secondary: var(--n-600);
  --text-muted: var(--n-500);
  --text-faint: var(--n-400);
  --text-invert: var(--n-0);

  /* Radii */
  --r-xs: 6px;
  --r-sm: 8px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-xl: 18px;
  --r-2xl: 24px;
  --r-full: 999px;

  /* Elevation - layered, low-opacity shadows; the console should feel
     printed onto the page rather than floating over it. */
  --sh-xs: 0 1px 2px rgba(13, 20, 32, 0.05);
  --sh-sm: 0 1px 2px rgba(13, 20, 32, 0.06), 0 1px 3px rgba(13, 20, 32, 0.04);
  --sh-md: 0 2px 4px rgba(13, 20, 32, 0.04), 0 6px 16px rgba(13, 20, 32, 0.07);
  --sh-lg: 0 8px 24px rgba(13, 20, 32, 0.10), 0 2px 6px rgba(13, 20, 32, 0.05);
  --sh-xl: 0 24px 56px rgba(13, 20, 32, 0.18), 0 6px 16px rgba(13, 20, 32, 0.08);
  --sh-focus: 0 0 0 3px var(--brand-100);

  /* Type */
  --font-fa: Vazirmatn, 'Segoe UI', Tahoma, system-ui, sans-serif;
  --font-en: Vazirmatn, Inter, system-ui, -apple-system, sans-serif;
  --font-num: Vazirmatn, ui-sans-serif, system-ui, sans-serif;

  --t-2xs: 11px;
  --t-xs: 12px;
  --t-sm: 13px;
  --t-md: 14px;
  --t-lg: 16px;
  --t-xl: 18px;
  --t-2xl: 22px;
  --t-3xl: 28px;

  /* Layout */
  --nav-w: 264px;
  --topbar-h: 60px;
  --content-max: 1240px;

  --ease: cubic-bezier(0.32, 0.72, 0, 1);
  --dur: 0.18s;

  /* -- Back-compat aliases ------------------------------------------------
     Earlier markup sets a handful of these directly via inline style
     (e.g. style="color:var(--accent-600)"). Keeping them mapped onto the
     new ramp means the old inline styles resolve to the new palette
     instead of silently falling back to nothing. */
  --ink-950: var(--n-950);
  --ink-900: var(--n-900);
  --ink-800: var(--n-800);
  --ink-700: var(--n-700);
  --ink-500: var(--n-500);
  --ink-300: var(--n-300);
  --ink-200: var(--n-200);
  --ink-100: var(--n-100);
  --ink-50: var(--n-50);
  --accent-600: var(--brand-600);
  --accent-500: var(--brand-500);
  --accent-300: var(--brand-300);
  --accent-100: var(--brand-100);
  --neutral-600: var(--n-600);
  --neutral-100: var(--border);
  --ok-100-legacy: var(--ok-100);
  --radius-md: var(--r-md);
  --radius-lg: var(--r-lg);
  --shadow-sm: var(--sh-sm);
  --shadow-md: var(--sh-md);
}

/* 3. Base ----------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
}

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  background: var(--bg-app);
  color: var(--text);
  font-family: var(--font-fa);
  font-size: var(--t-md);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

body[dir='ltr'] { font-family: var(--font-en); }

h1, h2, h3, h4 { margin: 0; line-height: 1.35; font-weight: 700; letter-spacing: -0.01em; }
p { margin: 0 0 0.75em; }
p:last-child { margin-bottom: 0; }

a { color: inherit; text-decoration: none; }

/* Buttons opt in to their appearance. Without clearing these two, any
   button that only sets layout/colour - the calendar's month label, its
   nav arrows, its day cells - renders inside the browser's default grey
   box with a grey bevel, which is where the stray boxes around the
   date-picker header came from. Everything that wants a surface
   (.db-btn, .ob-stepper button, ...) sets its own. */
button { font-family: inherit; font-size: inherit; cursor: pointer; background: none; border: 0; }
input, select, textarea { font-family: inherit; font-size: inherit; }

img { max-width: 100%; }

/* One consistent keyboard-focus treatment for everything interactive, and
   never on plain mouse clicks. */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--brand-500);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

::selection { background: var(--brand-100); color: var(--brand-800); }

/* Scrollbars inside panes (the order-builder cart, tables, the sidebar) -
   thin and neutral so a scrollable column doesn't announce itself with a
   fat OS bar. */
.ob-cart__scroll, .db-table-wrap, .db-nav {
  scrollbar-width: thin;
  scrollbar-color: var(--n-300) transparent;
}
.ob-cart__scroll::-webkit-scrollbar,
.db-table-wrap::-webkit-scrollbar { width: 8px; height: 8px; }
.ob-cart__scroll::-webkit-scrollbar-thumb,
.db-table-wrap::-webkit-scrollbar-thumb {
  background: var(--n-200);
  border-radius: var(--r-full);
}
.ob-cart__scroll::-webkit-scrollbar-thumb:hover { background: var(--n-300); }

/* 4. App shell ------------------------------------------------------------ */

.db-shell {
  display: flex;
  min-height: 100vh;
  min-height: 100dvh;
}

.db-sidebar {
  width: var(--nav-w);
  flex-shrink: 0;
  background: linear-gradient(180deg, var(--nav-bg-soft) 0%, var(--nav-bg) 32%);
  color: var(--nav-text);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  z-index: 40;
  border-inline-end: 1px solid rgba(0, 0, 0, 0.4);
}

.db-sidebar__brand {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 18px 18px 16px;
  border-bottom: 1px solid var(--nav-border);
}

.db-sidebar__brand-badge {
  width: 34px;
  height: 34px;
  border-radius: var(--r-md);
  background: linear-gradient(145deg, var(--brand-400), var(--brand-600) 70%);
  box-shadow: 0 2px 8px rgba(237, 28, 36, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.28);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: var(--t-md);
  color: #fff;
  flex-shrink: 0;
  letter-spacing: 0.02em;
}

.db-sidebar__brand-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.db-sidebar__brand-name {
  font-size: var(--t-md);
  font-weight: 700;
  color: var(--nav-text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.db-sidebar__brand-role {
  font-size: var(--t-2xs);
  color: var(--nav-text);
  letter-spacing: 0.02em;
}

.db-nav {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 12px 10px 16px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.db-nav__section {
  padding: 16px 12px 6px;
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(154, 166, 184, 0.65);
}
.db-nav__section:first-child { padding-top: 6px; }

.db-nav__link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border-radius: var(--r-md);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--nav-text);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.db-nav__link:hover { background: rgba(255, 255, 255, 0.055); color: var(--nav-text-strong); }

/* The active item is a soft translucent pill with a short brand bar on the
   inline-start edge, rather than a solid red block - it marks position
   without turning the whole sidebar into a colour field. */
.db-nav__link.is-active {
  background: rgba(255, 255, 255, 0.09);
  color: #fff;
  font-weight: 600;
}
.db-nav__link.is-active::before {
  content: '';
  position: absolute;
  inset-inline-start: -10px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 20px;
  border-radius: var(--r-full);
  background: var(--brand-500);
  box-shadow: 0 0 10px rgba(237, 28, 36, 0.7);
}

/* Base icon glyph. <db-icon> renders an inline SVG with this class; context
   classes (.db-nav__icon, .db-stat__icon svg, ...) adjust size/opacity. */
.db-i {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.db-i--sm { width: 15px; height: 15px; }
.db-i--lg { width: 22px; height: 22px; }

.db-nav__icon { opacity: 0.75; }
.db-nav__link.is-active .db-nav__icon,
.db-nav__link:hover .db-nav__icon { opacity: 1; }

.db-nav__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.db-sidebar__footer {
  padding: 12px 12px 14px;
  border-top: 1px solid var(--nav-border);
}

.db-user-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.04);
}
.db-user-chip__avatar {
  width: 32px;
  height: 32px;
  border-radius: var(--r-full);
  background: linear-gradient(145deg, #35405a, #222b3d);
  color: #dde3ee;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--t-xs);
  font-weight: 700;
  flex-shrink: 0;
  border: 1px solid rgba(255, 255, 255, 0.09);
}
.db-user-chip__body { min-width: 0; flex: 1; line-height: 1.35; }
.db-user-chip__name {
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--nav-text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.db-user-chip__logout {
  font-size: var(--t-xs);
  color: var(--nav-text);
  transition: color var(--dur) var(--ease);
}
.db-user-chip__logout:hover { color: var(--brand-400); }

.db-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.db-topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--topbar-h);
  padding: 10px 28px;
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border);
}

.db-topbar__toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border: 1px solid var(--border);
  background: var(--n-0);
  border-radius: var(--r-md);
  color: var(--n-700);
  transition: background var(--dur) var(--ease);
}
.db-topbar__toggle:hover { background: var(--bg-subtle); }
.db-topbar__toggle svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; }

.db-topbar__title {
  font-size: var(--t-md);
  font-weight: 700;
  letter-spacing: -0.01em;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.db-topbar__spacer { flex: 1; }

.db-topbar__user {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--text-secondary);
  padding: 5px 12px 5px 5px;
  border-radius: var(--r-full);
  border: 1px solid var(--border);
  background: var(--n-0);
  white-space: nowrap;
}
.db-topbar__avatar {
  width: 28px;
  height: 28px;
  border-radius: var(--r-full);
  background: linear-gradient(145deg, var(--n-700), var(--n-900));
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--t-2xs);
  font-weight: 700;
  flex-shrink: 0;
}

.db-content {
  flex: 1;
  padding: 26px 28px 56px;
  max-width: var(--content-max);
  width: 100%;
  margin: 0 auto;
}

/* Scrim behind the off-canvas sidebar on small screens. */
.db-scrim {
  position: fixed;
  inset: 0;
  background: rgba(12, 17, 26, 0.55);
  backdrop-filter: blur(2px);
  z-index: 39;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease);
}

@media (max-width: 1024px) {
  .db-topbar__toggle { display: inline-flex; }
  .db-topbar { padding-inline: 16px; }
  .db-content { padding: 20px 16px 64px; }

  .db-sidebar {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    transform: translateX(var(--nav-hide, 105%));
    transition: transform 0.26s var(--ease);
    box-shadow: var(--sh-xl);
  }
  [dir='rtl'] .db-sidebar { --nav-hide: 105%; }
  [dir='ltr'] .db-sidebar { --nav-hide: -105%; }
  .db-shell.is-nav-open .db-sidebar { transform: translateX(0); }
  .db-shell.is-nav-open .db-scrim { opacity: 1; pointer-events: auto; }
}

@media (max-width: 560px) {
  .db-topbar__user { padding: 4px; border: none; background: none; }
  .db-topbar__user .db-topbar__name { display: none; }
}

/* 5. Page furniture ------------------------------------------------------- */

.db-page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.db-page-title {
  font-size: var(--t-2xl);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.db-page-subtitle {
  font-size: var(--t-sm);
  color: var(--text-muted);
  margin: 5px 0 0;
  max-width: 68ch;
}

.db-page-header__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Back link above a detail-page title. */
.db-backlink {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--t-xs);
  font-weight: 500;
  color: var(--text-muted);
  margin-bottom: 10px;
  transition: color var(--dur) var(--ease);
}
.db-backlink:hover { color: var(--brand-600); }
.db-backlink svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
[dir='rtl'] .db-backlink svg { transform: scaleX(-1); }

/* Inline text link, e.g. "see all N" under a truncated card grid. */
.db-link {
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--brand-600);
  text-decoration: none;
}
.db-link:hover { text-decoration: underline; }

/* Filter / search strip above a list. */
.db-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 12px 14px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-xs);
  margin-bottom: 16px;
}
.db-toolbar__grow { flex: 1; min-width: 180px; }
.db-toolbar__spacer { flex: 1; }
/* A labelled control in a toolbar - date bounds need to say which end they
   are, and a bare date input cannot. */

/* Input with a leading magnifier, used for every list search box. */
.db-search {
  position: relative;
  display: block;
  min-width: 200px;
}
.db-search svg {
  position: absolute;
  inset-inline-start: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  stroke: var(--text-faint);
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  pointer-events: none;
}
.db-search .db-input { padding-inline-start: 36px; }

.db-section-title {
  font-size: var(--t-md);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
}

/* 6. Surfaces ------------------------------------------------------------- */

.db-card {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-xs);
  padding: 20px;
}
.db-card--flush { padding: 0; overflow: hidden; }
.db-card--sunken { background: var(--bg-subtle); box-shadow: none; }

.db-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
.db-card__title { font-size: var(--t-md); font-weight: 700; margin: 0; letter-spacing: -0.01em; }
.db-card__hint { font-size: var(--t-xs); color: var(--text-muted); margin: -8px 0 14px; }

.db-grid { display: grid; gap: 16px; }
.db-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.db-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.db-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1000px) {
  .db-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .db-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 680px) {
  .db-grid--2, .db-grid--3, .db-grid--4 { grid-template-columns: 1fr; }
}

/* Stat tile. Label sits above the figure so a row of tiles scans as a list
   of questions with answers, and the number itself gets the display size. */
.db-stat {
  position: relative;
  display: block;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 16px 18px 18px;
  box-shadow: var(--sh-xs);
  overflow: hidden;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.db-stat__label {
  font-size: var(--t-xs);
  font-weight: 500;
  color: var(--text-muted);
  margin: 0 0 6px;
  display: flex;
  align-items: center;
  gap: 7px;
}
.db-stat__value {
  font-size: var(--t-3xl);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.db-stat__value--text { font-size: var(--t-xl); letter-spacing: -0.01em; }
.db-stat__icon {
  position: absolute;
  inset-block-start: 16px;
  inset-inline-end: 16px;
  width: 34px;
  height: 34px;
  border-radius: var(--r-md);
  background: var(--bg-subtle);
  color: var(--n-500);
  display: flex;
  align-items: center;
  justify-content: center;
}
.db-stat__icon svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.db-stat__foot { font-size: var(--t-xs); color: var(--text-faint); margin-top: 8px; }

a.db-stat:hover {
  border-color: var(--n-200);
  box-shadow: var(--sh-md);
  transform: translateY(-1px);
}
a.db-stat:hover .db-stat__icon { background: var(--brand-50); color: var(--brand-600); }

/* Dashboard "recent events" feed - Submitted/Pending items across every
   admin queue (orders, returns, samples, proposals, agent approvals), most
   recent first, each row a link straight into the record so an admin can
   act on it without going through its list page first. */
.db-events {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.db-event {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 8px;
  border-radius: var(--r-md);
  text-decoration: none;
  color: inherit;
  transition: background var(--dur) var(--ease);
}
.db-event:not(:last-child) { border-bottom: 1px solid var(--border); }
.db-event:hover { background: var(--bg-subtle); }
.db-event__icon {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: var(--r-md);
  background: var(--bg-subtle);
  color: var(--n-500);
  display: flex;
  align-items: center;
  justify-content: center;
}
.db-event__icon svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.db-event__body { flex: 1; min-width: 0; }
.db-event__title {
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.db-event__subtitle {
  font-size: var(--t-xs);
  color: var(--text-faint);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.db-event__meta {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--t-xs);
  color: var(--text-faint);
}

/* 7. Data display --------------------------------------------------------- */

.db-table-wrap {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow-x: auto;
  box-shadow: var(--sh-xs);
}

.db-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
}

.db-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  text-align: start;
  padding: 11px 16px;
  color: var(--text-muted);
  font-weight: 600;
  font-size: var(--t-xs);
  letter-spacing: 0.02em;
  white-space: nowrap;
  background: var(--bg-subtle);
  border-bottom: 1px solid var(--border);
}

.db-table td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--n-100);
  vertical-align: middle;
  color: var(--text-secondary);
}
.db-table td:first-child { color: var(--text); }
.db-table tbody tr:last-child td { border-bottom: none; }
.db-table tbody tr { transition: background var(--dur) var(--ease); }
.db-table tbody tr:hover td { background: var(--n-25); }

/* Key/value variant: `th` inside tbody is a row label, not a column head. */
.db-table tbody th {
  text-align: start;
  padding: 12px 16px;
  width: 190px;
  font-weight: 500;
  font-size: var(--t-sm);
  color: var(--text-muted);
  background: var(--bg-subtle);
  border-bottom: 1px solid var(--n-100);
  white-space: nowrap;
}
.db-table tbody tr:last-child th { border-bottom: none; }

.db-table__link {
  color: var(--brand-600);
  font-weight: 600;
  transition: color var(--dur) var(--ease);
}
.db-table__link:hover { color: var(--brand-700); text-decoration: underline; text-underline-offset: 3px; }

.db-table__sub { font-size: var(--t-xs); color: var(--text-muted); margin-top: 2px; }
.db-table__sub--missing { font-style: italic; color: var(--text-faint); }
.db-table__num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.db-table__actions-cell { text-align: end; white-space: nowrap; width: 1%; }
.db-table tr.is-clickable { cursor: pointer; }

.db-table__thumb {
  width: 40px;
  height: 40px;
  border-radius: var(--r-sm);
  object-fit: cover;
  border: 1px solid var(--border);
  background-color: var(--bg-subtle);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b8c1ce' stroke-width='1.6'%3E%3Cpath d='M21 8l-9-5-9 5 9 5 9-5z'/%3E%3Cpath d='M3 8v8l9 5 9-5V8'/%3E%3Cpath d='M12 13v8'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 46%;
  display: block;
}

/* Card-stacked tables below 720px. Each `td` needs a data-label attribute;
   the header row is hidden and every cell becomes a label/value line, which
   beats horizontal scrolling for an agent checking orders on a phone. */
@media (max-width: 720px) {
  .db-table--stack thead { display: none; }
  .db-table--stack, .db-table--stack tbody, .db-table--stack tr, .db-table--stack td { display: block; width: 100%; }
  .db-table--stack tr {
    padding: 6px 4px 10px;
    border-bottom: 8px solid var(--bg-app);
  }
  .db-table--stack tbody tr:last-child { border-bottom: none; }
  .db-table--stack td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 7px 16px;
    border-bottom: none;
    text-align: end;
  }
  .db-table--stack td::before {
    content: attr(data-label);
    font-size: var(--t-xs);
    font-weight: 500;
    color: var(--text-muted);
    text-align: start;
    flex-shrink: 0;
  }
  .db-table--stack td:empty { display: none; }
  .db-table--stack td[data-label='']::before { content: none; }
  .db-table--stack tbody tr:hover td { background: none; }
  .db-table--stack .db-table__actions-cell { width: auto; justify-content: flex-end; }
  .db-table--stack .db-row-actions { flex-wrap: wrap; justify-content: flex-end; }
}

/* Badges - a status dot plus a label, on a tinted, bordered pill. */
.db-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px 3px 8px;
  border-radius: var(--r-full);
  font-size: var(--t-xs);
  font-weight: 600;
  line-height: 1.6;
  white-space: nowrap;
  background: var(--n-100);
  color: var(--n-600);
  border: 1px solid var(--n-150);
}
.db-badge::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: currentColor;
  flex-shrink: 0;
  opacity: 0.85;
}
.db-badge--ok { background: var(--ok-50); color: var(--ok-600); border-color: var(--ok-200); }
.db-badge--warn { background: var(--warn-50); color: var(--warn-600); border-color: var(--warn-200); }
.db-badge--danger { background: var(--danger-50); color: var(--danger-600); border-color: var(--danger-200); }
.db-badge--accent { background: var(--info-50); color: var(--info-600); border-color: var(--info-200); }
.db-badge--brand { background: var(--brand-50); color: var(--brand-600); border-color: var(--brand-200); }
.db-badge--plain::before { display: none; }
.db-badge--lg { font-size: var(--t-sm); padding: 4px 12px 4px 10px; }

/* Clickable badge for inline boolean toggles in a table row (e.g.
   is_published) - click the badge, it posts, the row updates in place. */
.db-badge-btn {
  cursor: pointer;
  transition: filter var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.db-badge-btn:hover { filter: brightness(0.97); box-shadow: var(--sh-xs); }
.db-badge-btn:disabled { opacity: 0.55; cursor: progress; }

/* Empty state - icon, headline, one line of guidance, optional action. */
.db-empty {
  padding: 52px 24px;
  text-align: center;
  color: var(--text-muted);
  font-size: var(--t-sm);
}
.db-empty__icon {
  width: 52px;
  height: 52px;
  margin: 0 auto 14px;
  border-radius: var(--r-lg);
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-faint);
}
.db-empty__icon svg { width: 24px; height: 24px; stroke: currentColor; fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.db-empty__title { font-size: var(--t-md); font-weight: 700; color: var(--text); margin: 0 0 4px; }
.db-empty__text { margin: 0 auto; max-width: 42ch; }
.db-empty__action { margin-top: 18px; }


/* 8. Controls ------------------------------------------------------------- */

.db-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 0 16px;
  height: 38px;
  border-radius: var(--r-md);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: -0.005em;
  border: 1px solid transparent;
  background: linear-gradient(180deg, var(--brand-500), var(--brand-600));
  color: #fff;
  box-shadow: 0 1px 2px rgba(13, 20, 32, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.16);
  white-space: nowrap;
  transition: background var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              transform var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.db-btn:hover { background: linear-gradient(180deg, var(--brand-600), var(--brand-700)); box-shadow: var(--sh-sm); }
.db-btn:active { transform: translateY(1px); box-shadow: none; }
.db-btn:focus-visible { outline: none; box-shadow: var(--sh-focus), 0 0 0 1px var(--brand-600); }
.db-btn:disabled, .db-btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.db-btn--secondary {
  background: var(--n-0);
  color: var(--n-800);
  border-color: var(--border-strong);
  box-shadow: var(--sh-xs);
}
.db-btn--secondary:hover { background: var(--bg-subtle); border-color: var(--n-300); box-shadow: var(--sh-sm); }

.db-btn--danger { background: linear-gradient(180deg, #e4463a, var(--danger-600)); }
.db-btn--danger:hover { background: linear-gradient(180deg, var(--danger-600), var(--danger-700)); }

.db-btn--ghost {
  background: transparent;
  color: var(--brand-600);
  box-shadow: none;
  border-color: transparent;
  padding-inline: 10px;
}
.db-btn--ghost:hover { background: var(--brand-50); box-shadow: none; }

.db-btn--subtle {
  background: var(--bg-sunken);
  color: var(--n-700);
  box-shadow: none;
}
.db-btn--subtle:hover { background: var(--n-150); box-shadow: none; }

.db-btn--sm { height: 32px; padding: 0 12px; font-size: var(--t-xs); border-radius: var(--r-sm); }
.db-btn--lg { height: 44px; padding: 0 22px; font-size: var(--t-md); }
.db-btn--block { width: 100%; }
.db-btn svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
.db-btn--sm svg { width: 14px; height: 14px; }


/* Form fields */
.db-field { margin-bottom: 16px; }
.db-field:last-child { margin-bottom: 0; }
.db-field > label {
  display: block;
  font-size: var(--t-xs);
  font-weight: 600;
  margin-bottom: 6px;
  color: var(--n-700);
  letter-spacing: 0.005em;
}
.db-field__hint { font-size: var(--t-xs); color: var(--text-muted); margin-top: 6px; line-height: 1.6; }
.db-field__req { color: var(--brand-600); font-weight: 700; }

.db-input, .db-select, .db-textarea {
  width: 100%;
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  font-size: var(--t-sm);
  background: var(--n-0);
  color: var(--text);
  box-shadow: var(--sh-xs);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background var(--dur) var(--ease);
  -webkit-appearance: none;
  appearance: none;
}
.db-textarea { height: auto; min-height: 84px; padding: 9px 12px; line-height: 1.7; resize: vertical; }
textarea.db-input { height: auto; min-height: 84px; padding: 9px 12px; line-height: 1.7; resize: vertical; }

.db-input::placeholder, .db-textarea::placeholder { color: var(--text-faint); }
.db-input:hover, .db-select:hover, .db-textarea:hover { border-color: var(--n-300); }
.db-input:focus, .db-select:focus, .db-textarea:focus {
  outline: none;
  border-color: var(--brand-400);
  box-shadow: var(--sh-focus);
  background: var(--n-0);
}
.db-input:disabled, .db-select:disabled, .db-textarea:disabled {
  background: var(--bg-subtle);
  color: var(--text-muted);
  cursor: not-allowed;
}

/* Native select needs its own caret once appearance is stripped. */
.db-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7788' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 15px;
  background-position: left 12px center;
  padding-inline-end: 12px;
  padding-inline-start: 34px;
  cursor: pointer;
}
[dir='ltr'] .db-select { background-position: right 12px center; padding-inline-start: 12px; padding-inline-end: 34px; }
select.db-input {
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7788' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 15px;
  background-position: left 12px center;
  padding-inline-start: 34px;
  cursor: pointer;
}

/* Input with a trailing affordance button (slug + "suggest", search + "go").
   The button keeps its intrinsic width and the input takes the rest, and
   the pair never wraps onto two lines the way a bare .db-flex would. */
.db-input-group {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: nowrap;
}
.db-input-group > .db-input,
.db-input-group > .db-select { flex: 1; min-width: 0; }
.db-input-group > .db-btn { flex-shrink: 0; }

/* Checkbox / radio - brand-tinted, comfortable hit area. */
input[type='checkbox'], input[type='radio'] {
  accent-color: var(--brand-600);
  width: 16px;
  height: 16px;
  cursor: pointer;
  flex-shrink: 0;
}

/* Checkbox rendered as a full-width selectable row, for the "is active",
   "is published" style options that used to be bare inline checkboxes. */
/* Stacked checkboxes need breathing room between them - two bordered cards
   flush against each other read as one control with a stray line through it. */
.db-check-group { display: flex; flex-direction: column; gap: 10px; }

/* Flash toast shown by the console shell after a navigation (e.g. "rule
   saved") - see DemesApi.setFlash/takeFlash. */
.db-flash {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 11px 14px;
  margin-bottom: 16px;
  border-radius: var(--r-md);
  border: 1px solid var(--ok-100);
  background: var(--ok-50);
  color: var(--ok-700);
  font-size: var(--t-sm);
  font-weight: 500;
}
.db-flash--error { border-color: var(--danger-200); background: var(--danger-50); color: var(--danger-700); }
.db-flash__close {
  margin-inline-start: auto;
  background: none; border: 0; cursor: pointer;
  font-size: 18px; line-height: 1; color: inherit; opacity: 0.6;
}
.db-flash__close:hover { opacity: 1; }

.db-check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-subtle);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--n-700);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.db-check:hover { border-color: var(--n-300); background: var(--n-100); }
.db-check input { margin-top: 3px; }
.db-check__text { line-height: 1.6; }
.db-check__hint { display: block; font-size: var(--t-xs); font-weight: 400; color: var(--text-muted); }

/* File input - the native control restyled into a dashed dropzone-ish row. */
input[type='file'] {
  font-size: var(--t-xs);
  color: var(--text-muted);
  max-width: 100%;
}
input[type='file']::file-selector-button {
  font-family: inherit;
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--n-800);
  background: var(--n-0);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  padding: 6px 12px;
  margin-inline-end: 10px;
  cursor: pointer;
  transition: background var(--dur) var(--ease);
}
input[type='file']::file-selector-button:hover { background: var(--bg-subtle); }

/* Collapsible section for secondary/rarely-needed fields (translations,
   descriptions, SEO) - one click instead of a wall of inputs. */
details.db-collapsible {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  margin-top: 16px;
  background: var(--bg-surface);
  box-shadow: var(--sh-xs);
  overflow: hidden;
}
details.db-collapsible > summary {
  cursor: pointer;
  padding: 13px 18px;
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--n-700);
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
  user-select: none;
  transition: background var(--dur) var(--ease);
}
details.db-collapsible > summary:hover { background: var(--bg-subtle); }
details.db-collapsible > summary::-webkit-details-marker { display: none; }
details.db-collapsible > summary::before {
  content: '';
  width: 8px;
  height: 8px;
  border-inline-end: 1.8px solid var(--text-faint);
  border-block-end: 1.8px solid var(--text-faint);
  transform: rotate(-45deg);
  transition: transform var(--dur) var(--ease);
  flex-shrink: 0;
  margin-inline-end: 2px;
}
[dir='rtl'] details.db-collapsible > summary::before { transform: rotate(135deg); }
details.db-collapsible[open] > summary::before { transform: rotate(45deg); }
[dir='rtl'] details.db-collapsible[open] > summary::before { transform: rotate(45deg); }
details.db-collapsible[open] > summary { border-bottom: 1px solid var(--border); }
details.db-collapsible .db-collapsible__body { padding: 18px; }

/* Buttons in a table's trailing actions cell. `nowrap` is load-bearing:
   .db-table__actions-cell is width:1%, so the column collapses to the
   content's min-content width - and for a *wrapping* flex container that
   width is the widest single button, not the sum, which stacks two short
   buttons into a column. Keeping the row unwrapped makes min-content the
   full row instead. It wraps again in the stacked mobile layout below,
   where the cell is full-width and overflow is the real risk. */
.db-row-actions { display: flex; flex-wrap: nowrap; gap: 8px; justify-content: flex-end; }

/* Sticky form footer for long editors, so Save is always one click away. */
.db-form-actions {
  position: sticky;
  bottom: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 24px;
  padding: 14px 18px;
  background: rgba(255, 255, 255, 0.88);
  backdrop-filter: saturate(180%) blur(10px);
  -webkit-backdrop-filter: saturate(180%) blur(10px);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-md);
}
.db-form-actions__spacer { flex: 1; }

/* Modal */
.db-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(12, 17, 26, 0.5);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 40px 16px;
  z-index: 60;
  overflow-y: auto;
  animation: db-fade-in 0.16s var(--ease);
}
.db-modal {
  background: var(--bg-surface);
  border-radius: var(--r-xl);
  width: 100%;
  max-width: 480px;
  padding: 22px;
  box-shadow: var(--sh-xl);
  border: 1px solid var(--border);
  animation: db-modal-in 0.2s var(--ease);
}
.db-modal__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
}
.db-modal__title { font-size: var(--t-lg); font-weight: 700; color: var(--text); letter-spacing: -0.01em; }
.db-modal__subtitle { font-size: var(--t-xs); color: var(--text-muted); margin-top: 3px; }
.db-modal__close {
  border: 1px solid transparent;
  background: none;
  border-radius: var(--r-sm);
  font-size: 20px;
  line-height: 1;
  color: var(--text-muted);
  padding: 4px 8px;
  flex-shrink: 0;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.db-modal__close:hover { background: var(--bg-subtle); color: var(--n-900); }
.db-modal__actions {
  display: flex;
  gap: 10px;
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}

@keyframes db-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes db-modal-in {
  from { opacity: 0; transform: translateY(-8px) scale(0.985); }
  to { opacity: 1; transform: none; }
}

/* 9. Feedback ------------------------------------------------------------- */

.db-error, .db-alert {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--danger-50);
  color: var(--danger-700);
  border: 1px solid var(--danger-200);
  border-radius: var(--r-md);
  padding: 11px 14px;
  font-size: var(--t-sm);
  line-height: 1.7;
  margin-bottom: 16px;
}
.db-error::before, .db-alert--danger::before {
  content: '';
  width: 16px;
  height: 16px;
  margin-top: 3px;
  flex-shrink: 0;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 8v5M12 16.5v.01'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 8v5M12 16.5v.01'/%3E%3C/svg%3E") center / contain no-repeat;
}
.db-alert--info { background: var(--info-50); color: var(--info-700); border-color: var(--info-200); }
.db-alert--warn { background: var(--warn-50); color: var(--warn-700); border-color: var(--warn-200); }
.db-alert--ok { background: var(--ok-50); color: var(--ok-700); border-color: var(--ok-200); }

.db-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 44px 20px;
  color: var(--text-muted);
  font-size: var(--t-sm);
}
.db-loading::before {
  content: '';
  width: 16px;
  height: 16px;
  border-radius: var(--r-full);
  border: 2px solid var(--n-200);
  border-top-color: var(--brand-500);
  animation: db-spin 0.7s linear infinite;
  flex-shrink: 0;
}
@keyframes db-spin { to { transform: rotate(360deg); } }

/* 10. Order console ------------------------------------------------------- */


/* Order window status banner */
.db-window-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  border-radius: var(--r-lg);
  padding: 14px 18px;
  margin-bottom: 18px;
  font-size: var(--t-sm);
  line-height: 1.7;
  border: 1px solid transparent;
}
.db-window-banner::before {
  content: '';
  width: 9px;
  height: 9px;
  border-radius: var(--r-full);
  flex-shrink: 0;
  background: currentColor;
}
.db-window-banner--open { background: var(--ok-50); color: var(--ok-600); border-color: var(--ok-200); }
.db-window-banner--none { background: var(--n-100); color: var(--n-600); border-color: var(--n-200); }
.db-window-banner strong { font-weight: 700; }


/* Image upload control */
.db-upload {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-lg);
  background: var(--bg-subtle);
}
.db-upload__preview {
  width: 76px;
  height: 76px;
  border-radius: var(--r-md);
  object-fit: cover;
  background-color: var(--n-0);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b8c1ce' stroke-width='1.6'%3E%3Cpath d='M21 8l-9-5-9 5 9 5 9-5z'/%3E%3Cpath d='M3 8v8l9 5 9-5V8'/%3E%3Cpath d='M12 13v8'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 40%;
  border: 1px solid var(--border);
  flex-shrink: 0;
}
/* Smaller preview, for uploads nested inside another card (the per-product
   package-type rows) where the 76px one would dominate the row. */
.db-upload__preview--sm { width: 56px; height: 56px; }
/* Upload sitting on a sunken surface needs its own white ground to stay
   readable as a control rather than melting into the card. */
.db-upload--on-card { background: var(--n-0); }
.db-upload__body { flex: 1; min-width: 0; }
.db-upload__body > label { display: block; font-size: var(--t-xs); font-weight: 600; color: var(--n-700); margin-bottom: 8px; }
.db-upload__hint { font-size: var(--t-xs); color: var(--text-muted); margin-top: 6px; word-break: break-all; line-height: 1.6; }

/* Promotion Rule editor rows */
.db-rule-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr) auto;
  gap: 8px;
  align-items: center;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-subtle);
}
@media (max-width: 900px) { .db-rule-row { grid-template-columns: 1fr; } }
.db-row-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: 1px solid transparent;
  background: none;
  border-radius: var(--r-sm);
  color: var(--text-faint);
  font-size: 17px;
  line-height: 1;
  flex-shrink: 0;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.db-row-remove:hover { color: var(--danger-600); background: var(--danger-50); }

/* --- Order builder: product browser + cart ------------------------------- */

.ob-shell {
  display: grid;
  /* DOM order is filter panel, product list, cart - matching the RTL
     reading order: filters start-side, cart end-side. */
  grid-template-columns: 236px minmax(0, 1fr) 320px;
  gap: 18px;
  align-items: start;
}
@media (max-width: 1100px) { .ob-shell { grid-template-columns: 1fr; } }

.ob-cart {
  position: sticky;
  top: 16px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-sm);
  padding: 16px;
  max-height: calc(100vh - 32px);
  display: flex;
  flex-direction: column;
}
.ob-cart__header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--t-sm);
  font-weight: 700;
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.ob-cart__count {
  margin-inline-start: auto;
  font-size: var(--t-xs);
  font-weight: 700;
  color: var(--brand-600);
  background: var(--brand-50);
  border: 1px solid var(--brand-100);
  border-radius: var(--r-full);
  padding: 1px 9px;
}
/* The one scrolling region of the cart: items plus the promotion panel.
 *
 * These have to share a single scroller rather than each managing their own
 * height. The cart is a fixed-height sticky column, so anything that grows
 * without a bound - and a busy period can easily produce six or more rule
 * hints - pushes the totals and the submit button straight out of the panel.
 * Header pinned at the top, totals/submit pinned at the bottom, everything
 * that can vary in length scrolls between them.
 *
 * min-height:0 is what actually makes it scroll: a flex child's default
 * min-height is auto, which lets it grow past its parent instead of
 * overflowing internally. */
.ob-cart__scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  margin: 0 -4px;
  padding: 0 4px;
}
.ob-cart__foot { flex-shrink: 0; }
.ob-cart__list { display: flex; flex-direction: column; gap: 8px; }
.ob-cart__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--n-0);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.ob-cart__item:hover { border-color: var(--n-300); box-shadow: var(--sh-xs); }
.ob-cart__thumb {
  width: 42px;
  height: 42px;
  border-radius: var(--r-sm);
  object-fit: cover;
  border: 1px solid var(--border);
  background-color: var(--bg-subtle);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b8c1ce' stroke-width='1.6'%3E%3Cpath d='M21 8l-9-5-9 5 9 5 9-5z'/%3E%3Cpath d='M3 8v8l9 5 9-5V8'/%3E%3Cpath d='M12 13v8'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 46%;
  flex-shrink: 0;
}
.ob-cart__item-body { flex: 1; min-width: 0; }
.ob-cart__item-title {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ob-cart__item-meta { font-size: var(--t-2xs); color: var(--text-muted); margin-top: 1px; }
.ob-cart__remove {
  border: none;
  background: none;
  color: var(--text-faint);
  font-size: 15px;
  line-height: 1;
  padding: 4px 6px;
  border-radius: var(--r-xs);
  flex-shrink: 0;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ob-cart__remove:hover { color: var(--danger-600); background: var(--danger-50); }
.ob-cart__totals {
  border-top: 1px solid var(--border);
  margin-top: 12px;
  padding-top: 12px;
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
}
.ob-cart__totals-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  color: var(--text-secondary);
  padding: 3px 0;
}
.ob-cart__totals-row--strong {
  font-weight: 700;
  color: var(--text);
  border-top: 1px dashed var(--border-strong);
  margin-top: 5px;
  padding-top: 8px;
}

/* Quantity stepper */
.ob-stepper {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-full);
  overflow: hidden;
  flex-shrink: 0;
  background: var(--n-0);
  box-shadow: var(--sh-xs);
}
.ob-stepper button {
  width: 30px;
  height: 30px;
  border: none;
  background: var(--n-0);
  font-size: 15px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--n-700);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ob-stepper button:hover:not(:disabled) { background: var(--brand-50); color: var(--brand-600); }
.ob-stepper button:disabled { opacity: 0.35; cursor: not-allowed; }
.ob-stepper__value {
  min-width: 34px;
  text-align: center;
  font-size: var(--t-sm);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  border-inline: 1px solid var(--border);
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ob-stepper--active { border-color: var(--brand-300); box-shadow: 0 0 0 3px var(--brand-50); }
.ob-stepper--active .ob-stepper__value { color: var(--brand-600); }

.ob-search { margin-bottom: 16px; }

.ob-product-list__header {
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: space-between;
  margin-bottom: 12px;
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--text-muted);
}

.ob-product-list { display: flex; flex-direction: column; gap: 10px; }

.ob-product-card {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 12px;
  box-shadow: var(--sh-xs);
  transition: box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.ob-product-card:hover { box-shadow: var(--sh-md); border-color: var(--n-200); }
.ob-product-card.is-in-cart { border-color: var(--brand-200); background: linear-gradient(180deg, var(--brand-50) 0%, var(--n-0) 46px); }
.ob-product-card__head { display: flex; align-items: center; gap: 12px; }
.ob-product-card__thumb {
  width: 60px;
  height: 60px;
  border-radius: var(--r-md);
  object-fit: cover;
  border: 1px solid var(--border);
  background-color: var(--bg-subtle);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b8c1ce' stroke-width='1.6'%3E%3Cpath d='M21 8l-9-5-9 5 9 5 9-5z'/%3E%3Cpath d='M3 8v8l9 5 9-5V8'/%3E%3Cpath d='M12 13v8'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 46%;
  flex-shrink: 0;
}
.ob-product-card__body { min-width: 0; flex: 1; }
.ob-product-card__title { font-size: var(--t-md); font-weight: 700; letter-spacing: -0.01em; line-height: 1.4; }
.ob-product-card__meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: var(--t-xs);
  color: var(--text-muted);
  margin-top: 3px;
}
.ob-product-card__sku {
  font-size: var(--t-2xs);
  font-weight: 600;
  color: var(--text-faint);
  background: var(--bg-sunken);
  border-radius: var(--r-xs);
  padding: 0 6px;
}
.ob-product-card__toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-inline-start: auto;
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--brand-600);
  background: var(--brand-50);
  border: 1px solid var(--brand-100);
  border-radius: var(--r-full);
  padding: 5px 12px;
  flex-shrink: 0;
  transition: background var(--dur) var(--ease);
}
.ob-product-card__toggle:hover { background: var(--brand-100); }
.ob-product-card__toggle-caret {
  width: 7px;
  height: 7px;
  border-inline-end: 1.6px solid currentColor;
  border-block-end: 1.6px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  transition: transform var(--dur) var(--ease);
}
.ob-product-card__toggle.is-open .ob-product-card__toggle-caret { transform: rotate(-45deg) translate(-2px, -2px); }

.ob-package-table {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px dashed var(--border-strong);
  display: flex;
  flex-direction: column;
  gap: 2px;
  animation: db-expand 0.18s var(--ease);
}
@keyframes db-expand { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

.ob-package-row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px;
  border-radius: var(--r-md);
  transition: background var(--dur) var(--ease);
}
.ob-package-row:hover { background: var(--bg-subtle); }
.ob-package-row__thumb {
  width: 42px;
  height: 42px;
  border-radius: var(--r-sm);
  object-fit: cover;
  border: 1px solid var(--border);
  background-color: var(--bg-subtle);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b8c1ce' stroke-width='1.6'%3E%3Cpath d='M21 8l-9-5-9 5 9 5 9-5z'/%3E%3Cpath d='M3 8v8l9 5 9-5V8'/%3E%3Cpath d='M12 13v8'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 46%;
  flex-shrink: 0;
}
.ob-package-row__body { flex: 1; min-width: 0; }
.ob-package-row__label { font-size: var(--t-sm); font-weight: 600; }
.ob-package-row__meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: var(--t-xs);
  color: var(--text-muted);
  margin-top: 1px;
}
.ob-package-row__moq,
.ob-product-card__moq {
  font-size: var(--t-2xs);
  font-weight: 600;
  color: var(--warn-600);
  background: var(--warn-50);
  border: 1px solid var(--warn-200);
  border-radius: var(--r-xs);
  padding: 0 6px;
}

/* Rules stamped onto the product card itself. Green = something to gain,
   red = something that constrains you; the full text lives in the title
   attribute so the card stays scannable. */
.ob-product-card__rules {
  display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px;
}
.ob-product-rule {
  font-size: var(--t-2xs);
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 999px;
  cursor: help;
  color: var(--ok-700);
  background: var(--ok-50);
  border: 1px solid var(--ok-100);
}
.ob-product-rule--requirement {
  color: var(--danger-700);
  background: var(--danger-50);
  border-color: var(--danger-200);
}

.ob-filter-panel {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: 16px;
  box-shadow: var(--sh-xs);
  position: sticky;
  top: 16px;
}
.ob-filter-search { margin-bottom: 16px; }
.ob-filter-group { margin-bottom: 8px; }
.ob-filter-group__title {
  font-size: var(--t-2xs);
  font-weight: 700;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  margin-bottom: 8px;
}
.ob-filter-checkbox {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: var(--t-sm);
  padding: 7px 8px;
  margin: 0 -8px;
  border-radius: var(--r-sm);
  cursor: pointer;
  color: var(--text-secondary);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ob-filter-checkbox:hover { background: var(--bg-subtle); color: var(--text); }
.ob-filter-checkbox__count {
  margin-inline-start: auto;
  font-size: var(--t-2xs);
  font-weight: 600;
  color: var(--text-faint);
  background: var(--bg-sunken);
  border-radius: var(--r-full);
  padding: 1px 7px;
  font-variant-numeric: tabular-nums;
}

.ob-empty-hint {
  text-align: center;
  color: var(--text-muted);
  font-size: var(--t-sm);
  padding: 28px 12px;
  line-height: 1.8;
}

.ob-main { min-width: 0; }

/* --- Standalone order console -------------------------------------------
   The "new order" / "edit draft" routes render their own full-width shell
   instead of sitting inside db-shell's sidebar layout: placing an order is
   the agent's single most frequent task and shouldn't lose ~264px to a
   sidebar it doesn't need. Everything below is driven by the `standalone`
   prop on <order-builder>. */

.ob-root--standalone { min-height: 100vh; min-height: 100dvh; padding-bottom: 0; background: var(--bg-app); }

.oc-topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 12px 24px;
  background: linear-gradient(180deg, var(--nav-bg-soft), var(--nav-bg));
  color: #fff;
  box-shadow: var(--sh-md);
}
.oc-topbar__row { display: flex; align-items: center; gap: 12px; }
.oc-topbar__menu {
  display: none;
  flex-direction: column;
  gap: 4px;
  width: 36px;
  height: 36px;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.07);
  border-radius: var(--r-md);
  flex-shrink: 0;
  transition: background var(--dur) var(--ease);
}
.oc-topbar__menu:hover { background: rgba(255, 255, 255, 0.14); }
.oc-topbar__menu-bar { width: 16px; height: 1.8px; background: #fff; border-radius: 1px; }

.oc-topbar__title { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; overflow: hidden; }
.oc-topbar__title strong {
  font-size: var(--t-md);
  font-weight: 700;
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.oc-topbar__info { font-size: var(--t-xs); color: var(--nav-text); line-height: 1.7; }

.oc-topbar__dropzone {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--t-xs);
  color: #dbe2ee;
}
.oc-topbar__dropzone--inline { flex-shrink: 0; }
.oc-topbar__dropzone--inline strong { font-size: var(--t-sm); font-weight: 700; }
.oc-topbar__dropzone-sep { color: rgba(255, 255, 255, 0.22); }
.oc-topbar__dropzone--subnav { display: none; }
.oc-topbar__dropzone-change {
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  border-radius: var(--r-full);
  padding: 3px 12px;
  font-size: var(--t-2xs);
  font-weight: 600;
  flex-shrink: 0;
  transition: background var(--dur) var(--ease);
}
.oc-topbar__dropzone-change:hover { background: rgba(255, 255, 255, 0.18); }

/* Full-page dropzone picker */
.dz-pick { max-width: 580px; margin: 0 auto; padding: 26px 16px 48px; }
.dz-pick__toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.dz-pick__search { flex: 1; margin-bottom: 0; }
.dz-pick__list { display: flex; flex-direction: column; gap: 8px; }
.dz-pick__item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  border: 1px solid var(--border);
  background: var(--bg-surface);
  border-radius: var(--r-lg);
  padding: 14px 16px;
  text-align: start;
  box-shadow: var(--sh-xs);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.dz-pick__item:hover {
  border-color: var(--brand-300);
  box-shadow: var(--sh-md);
  transform: translateY(-1px);
}
.dz-pick__item-name { font-size: var(--t-md); font-weight: 700; color: var(--text); }
.dz-pick__item-meta { font-size: var(--t-xs); color: var(--text-muted); }


.oc-topbar__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.07);
  color: #fff;
  font-size: 20px;
  line-height: 1;
  flex-shrink: 0;
  transition: background var(--dur) var(--ease);
}
.oc-topbar__close:hover { background: rgba(255, 255, 255, 0.18); }

.oc-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: none;
  background: var(--bg-sunken);
  border-radius: var(--r-full);
  font-size: 17px;
  line-height: 1;
  color: var(--n-700);
  flex-shrink: 0;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.oc-icon-btn:hover { background: var(--brand-50); color: var(--brand-600); }

.oc-drawer-overlay {
  position: fixed;
  inset: 0;
  background: rgba(12, 17, 26, 0.55);
  backdrop-filter: blur(2px);
  z-index: 60;
  display: flex;
  animation: db-fade-in 0.16s var(--ease);
}
.oc-drawer {
  width: 268px;
  max-width: 82vw;
  height: 100%;
  background: linear-gradient(180deg, var(--nav-bg-soft), var(--nav-bg));
  padding: 18px 14px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  box-shadow: var(--sh-xl);
}
.oc-drawer__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; padding-inline: 4px; }
.oc-drawer__title { font-weight: 700; font-size: var(--t-md); color: #fff; }
.oc-drawer a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--r-md);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--nav-text);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.oc-drawer a:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }
.oc-drawer svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; opacity: 0.8; }
.oc-drawer__footer {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--nav-border);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ob-root--standalone .ob-shell { padding: 18px 24px 28px; }

/* Order-window toast - only shown when the window is upcoming/closed, i.e.
   exactly the cases that actually block ordering. Auto-dismisses. */
.oc-toast {
  position: fixed;
  top: 78px;
  inset-inline: 0;
  margin-inline: auto;
  width: fit-content;
  max-width: min(560px, calc(100vw - 32px));
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 13px 16px;
  border-radius: var(--r-lg);
  font-size: var(--t-sm);
  line-height: 1.75;
  box-shadow: var(--sh-lg);
  border: 1px solid transparent;
  z-index: 70;
}
.oc-toast--upcoming { background: var(--warn-50); color: var(--warn-700); border-color: var(--warn-200); }
.oc-toast--none { background: var(--n-100); color: var(--n-700); border-color: var(--n-200); }
.oc-toast__close {
  border: none;
  background: transparent;
  font-size: 17px;
  line-height: 1;
  color: inherit;
  opacity: 0.6;
  flex-shrink: 0;
  padding: 0 2px;
}
.oc-toast__close:hover { opacity: 1; }

.oc-toast-fade-enter-active, .oc-toast-fade-leave-active { transition: opacity 0.22s var(--ease), transform 0.22s var(--ease); }
.oc-toast-fade-enter-from, .oc-toast-fade-leave-to { opacity: 0; transform: translateY(-8px); }

.oc-fullpage-loading {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: var(--t-sm);
  padding: 24px;
  text-align: center;
}

.oc-overlay-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(12, 17, 26, 0.5);
  z-index: 50;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s var(--ease);
}
.oc-overlay-backdrop.is-open { opacity: 1; pointer-events: auto; }

.ob-filter-toggle-inline {
  display: none;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
  border-radius: var(--r-full);
  border: 1px solid var(--border-strong);
  background: var(--n-0);
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--n-700);
  flex-shrink: 0;
  box-shadow: var(--sh-xs);
}
.ob-filter-toggle-inline__badge {
  background: var(--brand-600);
  color: #fff;
  border-radius: var(--r-full);
  min-width: 17px;
  height: 17px;
  font-size: var(--t-2xs);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
}

/* --- Order review / order summary pages ---------------------------------
   Read top to bottom like a document, so a normal two-column flow rather
   than the fixed-viewport pattern order-builder uses. dir="rtl" plus DOM
   order [main, sidebar] puts main on the right without a reversal hack. */

.orv2-page { max-width: 1080px; margin: 0 auto; padding: 26px 20px 56px; }
.orv2-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 20px; }
.orv2-header__title { font-size: var(--t-2xl); font-weight: 800; letter-spacing: -0.02em; margin: 0 0 4px; color: var(--text); }
.orv2-header__subtitle { font-size: var(--t-sm); color: var(--text-muted); margin: 0 0 14px; max-width: 60ch; }

/* Two-step progress trail on the review screen. */
.orv2-steps { display: flex; align-items: center; gap: 6px; }
.orv2-step {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--text-muted);
  background: var(--n-0);
  border: 1px solid var(--border);
  padding: 5px 13px;
  border-radius: var(--r-full);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.orv2-step:hover { border-color: var(--n-300); color: var(--text); }
.orv2-step--active {
  background: linear-gradient(180deg, var(--brand-500), var(--brand-600));
  border-color: transparent;
  color: #fff;
  cursor: default;
  box-shadow: 0 1px 6px rgba(237, 28, 36, 0.3);
}
.orv2-step--active:hover { color: #fff; }

.orv2-back-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--r-full);
  border: 1px solid var(--border-strong);
  background: var(--n-0);
  font-size: 16px;
  color: var(--n-600);
  cursor: pointer;
  box-shadow: var(--sh-xs);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.orv2-back-btn:hover { background: var(--bg-subtle); color: var(--n-900); }
.orv2-back-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.orv2-error { margin-bottom: 14px; }

.orv2-grid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); gap: 18px; align-items: start; }
.orv2-mt { margin-top: 16px; }
.orv2-card__title {
  font-size: var(--t-md);
  font-weight: 700;
  margin: 0 0 14px;
  color: var(--text);
  letter-spacing: -0.01em;
  display: flex;
  align-items: center;
  gap: 8px;
}
.orv2-card__title-count {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--text-muted);
  background: var(--bg-sunken);
  border-radius: var(--r-full);
  padding: 1px 9px;
}

.orv2-info-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; }
.orv2-info-item__label { font-size: var(--t-xs); color: var(--text-muted); margin-bottom: 3px; }
.orv2-info-item__value { font-size: var(--t-md); font-weight: 600; color: var(--text); }

.orv2-item-list { display: flex; flex-direction: column; gap: 8px; }
.orv2-item-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--n-0);
  transition: border-color var(--dur) var(--ease);
}
.orv2-item-row:hover { border-color: var(--n-300); }
.orv2-item-avatar {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: var(--r-md);
  background: linear-gradient(145deg, var(--n-600), var(--n-800));
  color: #fff;
  font-size: var(--t-sm);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.orv2-item-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.orv2-item-body { flex: 1; min-width: 0; }
.orv2-item-title { font-size: var(--t-sm); font-weight: 600; color: var(--text); }
.orv2-item-meta { font-size: var(--t-xs); color: var(--text-muted); margin-top: 2px; }
.orv2-item-qty {
  flex-shrink: 0;
  font-size: var(--t-sm);
  font-weight: 700;
  color: var(--n-700);
  background: var(--bg-sunken);
  border-radius: var(--r-sm);
  padding: 3px 10px;
  font-variant-numeric: tabular-nums;
}

.orv2-sidebar { position: sticky; top: 16px; }
.orv2-summary-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: var(--t-sm);
  color: var(--text-secondary);
  padding: 6px 0;
  font-variant-numeric: tabular-nums;
}
.orv2-summary-row--total {
  font-weight: 700;
  font-size: var(--t-md);
  color: var(--text);
  border-top: 1px solid var(--border);
  margin-top: 6px;
  padding-top: 12px;
}
.orv2-confirm {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: var(--t-xs);
  line-height: 1.7;
  color: var(--n-700);
  margin-top: 18px;
  padding: 11px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-subtle);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease);
}
.orv2-confirm:hover { border-color: var(--n-300); }
.orv2-confirm input { margin-top: 3px; flex-shrink: 0; }

.orv2-order-title { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 2px; }
.orv2-order-title .orv2-header__title { margin: 0; }
.orv2-promo-list { display: flex; flex-direction: column; gap: 10px; }
.orv2-promo-item {
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-inline-start: 3px solid var(--ok-600);
  border-radius: var(--r-md);
  background: var(--bg-subtle);
}
.orv2-promo-item strong { font-size: var(--t-sm); }
.orv2-promo-item--blocked { border-inline-start-color: var(--danger-600); }
.orv2-promo-item--manual { border-inline-start-color: var(--warn-600); }
.orv2-promo-item__meta { font-size: var(--t-xs); color: var(--text-muted); margin-top: 4px; }

/* ---------------------------------------------------------------------------
   Promotions in the order builder.

   Three states, deliberately colour-coded rather than merely listed, because
   they demand three different reactions from the agent: red = you cannot
   submit this, green = you have earned this, amber = you are close to
   earning this. A flat list of grey rows would make the blocking one easy to
   scroll past, and the blocking one is the whole reason the panel exists.
--------------------------------------------------------------------------- */
.ob-promo { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; }
.ob-promo__group { display: flex; flex-direction: column; gap: 6px; }
.ob-promo__title {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--t-xs); font-weight: 600; color: var(--text-muted);
}
.ob-promo__item {
  padding: 9px 11px;
  border-radius: var(--r-sm);
  font-size: var(--t-xs);
  line-height: 1.7;
  border: 1px solid transparent;
}
.ob-promo__item strong { font-weight: 600; }
.ob-promo__item--blocked {
  background: var(--danger-50); border-color: var(--danger-200); color: var(--danger-700);
}
.ob-promo__item--earned {
  background: var(--ok-50); border-color: var(--ok-100); color: var(--ok-700);
}
.ob-promo__item--near {
  background: var(--warn-50); border-color: var(--warn-200); color: var(--warn-700);
}
.ob-promo__bar {
  height: 4px; border-radius: 999px; background: var(--warn-200);
  margin-top: 6px; overflow: hidden;
}
.ob-promo__bar span { display: block; height: 100%; background: var(--warn-600); border-radius: 999px; }
.ob-promo__loading { font-size: var(--t-xs); color: var(--text-muted); }

/* Exclusivity notice. Deliberately not red - nothing is wrong and nothing is
   blocked; the agent has been given something and is being told the terms.
   Neutral-emphatic sits between "you won" green and "you are stuck" red. */
.ob-promo__item--exclusive {
  background: var(--bg-subtle);
  border-color: var(--n-200);
  color: var(--n-700);
}
.ob-promo__exclusive-head { display: flex; align-items: center; gap: 6px; margin-bottom: 3px; }
.ob-promo__exclusive-badge {
  font-size: var(--t-2xs);
  font-weight: 700;
  color: var(--warn-700);
  background: var(--warn-50);
  border: 1px solid var(--warn-200);
  border-radius: var(--r-full);
  padding: 0 7px;
}
.ob-promo__suppressed {
  margin: 5px 0 0;
  padding-inline-start: 16px;
  color: var(--text-muted);
  text-decoration: line-through;
}
.ob-promo__suppressed-note { margin-top: 5px; color: var(--text-muted); }

.ob-rules__badge-excl {
  font-size: var(--t-2xs);
  font-weight: 700;
  color: var(--warn-700);
  background: var(--warn-50);
  border: 1px solid var(--warn-200);
  border-radius: var(--r-full);
  padding: 0 6px;
  margin-inline-start: 5px;
}
.ob-rules__excl-note { color: var(--warn-700); }
.ob-promo__count {
  margin-inline-start: auto;
  font-weight: 700;
  color: var(--warn-700);
  background: var(--warn-50);
  border: 1px solid var(--warn-200);
  border-radius: var(--r-full);
  padding: 0 7px;
}
.ob-promo__more {
  align-self: flex-start;
  background: none;
  border: 0;
  padding: 2px 0;
  font: inherit;
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--warn-700);
  cursor: pointer;
  text-decoration: underline;
}

/* The "rules of the game" panel above the product list - collapsed by
   default so it informs without pushing the products themselves off screen. */
.ob-rules {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-surface);
  margin-bottom: 14px;
  overflow: hidden;
}
.ob-rules__toggle {
  width: 100%; display: flex; align-items: center; gap: 8px;
  padding: 11px 14px; background: none; border: 0; cursor: pointer;
  font: inherit; font-size: var(--t-sm); font-weight: 600; color: inherit;
  text-align: start;
}
.ob-rules__toggle:hover { background: var(--bg-subtle); }
.ob-rules__badge {
  margin-inline-start: auto; font-size: var(--t-xs); font-weight: 500;
  color: var(--text-muted);
}
.ob-rules__body { padding: 0 14px 12px; display: flex; flex-direction: column; gap: 10px; }
.ob-rules__rule {
  padding: 10px 12px; border-radius: var(--r-sm); background: var(--bg-subtle);
  border-inline-start: 3px solid var(--ok-600); font-size: var(--t-xs); line-height: 1.8;
}
.ob-rules__rule--requirement { border-inline-start-color: var(--danger-600); }
.ob-rules__rule strong { display: block; font-size: var(--t-sm); margin-bottom: 2px; }
.ob-rules__rule ul { margin: 4px 0 0; padding-inline-start: 16px; color: var(--text-muted); }

/* Money summary block on invoice screens. */
.db-totals {
  margin-inline-start: auto;
  width: 100%;
  max-width: 340px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-xs);
  padding: 16px 18px;
  font-variant-numeric: tabular-nums;
}
.db-totals__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  font-size: var(--t-sm);
  color: var(--text-secondary);
  padding: 7px 0;
}
.db-totals__row--grand {
  font-size: var(--t-lg);
  font-weight: 800;
  color: var(--text);
  border-top: 1px solid var(--border);
  margin-top: 6px;
  padding-top: 13px;
  letter-spacing: -0.01em;
}
.db-totals__row .db-input { max-width: 130px; text-align: end; height: 34px; }

@media (max-width: 900px) {
  .orv2-grid { grid-template-columns: 1fr; }
  .orv2-sidebar { position: static; }
}
@media (max-width: 640px) {
  .orv2-page { padding: 18px 14px 44px; }
  .orv2-header { flex-direction: row-reverse; }
  .orv2-header__title { font-size: var(--t-xl); }
}

.ob-bottom-bar { display: none; }
.ob-cart__drawer-header, .ob-filter-panel__drawer-header {
  display: none;
  align-items: center;
  justify-content: space-between;
  font-weight: 700;
  font-size: var(--t-md);
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}

/* Below this width the builder collapses to one column; in standalone mode
   the cart and filter columns additionally become slide-up sheets driven by
   the header cart chip, the inline filter button and a fixed bottom bar. */
@media (max-width: 1100px) {
  .ob-root--standalone { padding-bottom: 84px; }
  .oc-topbar__menu { display: flex; }
  .oc-topbar__dropzone--inline { display: none; }
  .oc-topbar__dropzone--subnav { display: flex; }
  .ob-filter-panel { position: static; }

  .ob-root--standalone .ob-cart__drawer-header,
  .ob-root--standalone .ob-filter-panel__drawer-header { display: flex; }

  .ob-root--standalone .ob-cart {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    top: auto;
    max-height: 84vh;
    border-radius: var(--r-2xl) var(--r-2xl) 0 0;
    transform: translateY(110%);
    transition: transform 0.28s var(--ease);
    z-index: 55;
    box-shadow: 0 -10px 40px rgba(12, 17, 26, 0.28);
    padding-bottom: max(16px, env(safe-area-inset-bottom));
  }
  .ob-root--standalone .ob-cart.is-open { transform: translateY(0); }

  .ob-filter-toggle-inline { display: inline-flex; }
  .ob-root--standalone .ob-filter-panel {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    top: auto;
    max-height: 78vh;
    overflow-y: auto;
    border-radius: var(--r-2xl) var(--r-2xl) 0 0;
    transform: translateY(110%);
    transition: transform 0.28s var(--ease);
    z-index: 55;
    box-shadow: 0 -10px 40px rgba(12, 17, 26, 0.28);
    padding-bottom: max(16px, env(safe-area-inset-bottom));
  }
  .ob-root--standalone .ob-filter-panel.is-open { transform: translateY(0); }

  .ob-root--standalone .ob-bottom-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    padding: 12px 16px max(12px, env(safe-area-inset-bottom));
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: saturate(180%) blur(12px);
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    border-top: 1px solid var(--border);
    box-shadow: 0 -4px 20px rgba(12, 17, 26, 0.08);
    z-index: 45;
  }
  .ob-bottom-bar__info { display: flex; flex-direction: column; font-size: var(--t-xs); color: var(--text-muted); line-height: 1.5; }
  .ob-bottom-bar__info strong { font-size: var(--t-md); color: var(--text); font-weight: 700; }
}

@media (max-width: 480px) {
  .oc-topbar { padding: 10px 14px; }
  .oc-toast { top: 72px; font-size: var(--t-xs); }
  .ob-root--standalone .ob-shell { padding-inline: 14px; }
  .ob-product-card__head { flex-wrap: wrap; }
  .ob-product-card__toggle { margin-inline-start: 0; }
}

/* 10b. Order detail (admin) ------------------------------------------------
   The admin's order screen is a *review* surface: an operator opens it to
   answer "what is this order, is it sane, and what do I do with it" in a few
   seconds. So the page is split in two - a wide reading column (items,
   notes, promotions) and a narrow sticky action rail (where the order is in
   its lifecycle, the status control, the invoice). The rail staying in view
   while the item list scrolls is the whole point: the decision and the
   evidence for it are never on different screens.
   ------------------------------------------------------------------------ */

/* Header: the identity line (number + status) plus the four facts that
   qualify an order - who, where, which window, when. Inline as a meta row
   rather than a card of their own, because they're read once and then
   ignored; the items are what the operator actually studies. */
.ordv-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 18px;
}
.ordv-head__title {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: var(--t-2xl);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0;
}
.ordv-head__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
  margin-top: 10px;
  font-size: var(--t-xs);
  color: var(--text-muted);
}
.ordv-head__meta-item { display: inline-flex; align-items: center; gap: 6px; }
.ordv-head__meta-item strong { color: var(--text-secondary); font-weight: 600; }
.ordv-head__meta-item svg {
  width: 14px;
  height: 14px;
  stroke: var(--text-faint);
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}
.ordv-head__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.ordv-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  align-items: start;
  gap: 18px;
}
.ordv-main { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.ordv-side {
  position: sticky;
  top: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Card header for the flush (padding-less) item card. */
.ordv-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
.ordv-count {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--text-muted);
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  padding: 2px 10px;
}

/* Item row: thumbnail + title + per-row note stacked in one cell, so the
   remaining columns stay narrow and the numbers line up in a scannable
   rail on the far side. */
.ordv-product { display: flex; align-items: center; gap: 12px; min-width: 0; }
.ordv-product__thumb {
  width: 40px;
  height: 40px;
  border-radius: var(--r-md);
  object-fit: cover;
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ordv-product__thumb svg {
  width: 18px;
  height: 18px;
  stroke: var(--text-faint);
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ordv-product__body { min-width: 0; }
.ordv-product__name { display: block; font-weight: 600; color: var(--text); }
.ordv-product__note { display: block; font-size: var(--t-xs); color: var(--text-muted); margin-top: 2px; }

/* Totals live in the item card's own footer instead of a detached box -
   a sum belongs to the column it sums. */
.ordv-items__foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 14px 32px;
  padding: 14px 18px;
  border-top: 1px solid var(--border);
  background: var(--bg-subtle);
}
.ordv-stat { display: flex; flex-direction: column; gap: 2px; min-width: 84px; }
.ordv-stat__label { font-size: var(--t-xs); color: var(--text-muted); }
.ordv-stat__value { font-size: var(--t-md); font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.ordv-stat--grand .ordv-stat__value { font-size: var(--t-lg); font-weight: 800; letter-spacing: -0.01em; }

/* Lifecycle timeline. Reached states carry their timestamp, the pending
   one is drawn hollow - so "approved but not yet completed" is legible at
   a glance without reading a single word. */
.ordv-timeline { display: flex; flex-direction: column; }
.ordv-tl {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  gap: 10px;
  padding-bottom: 14px;
  position: relative;
}
.ordv-tl::before {
  content: '';
  position: absolute;
  inset-inline-start: 10px;
  top: 22px;
  bottom: 0;
  width: 2px;
  background: var(--border);
}
.ordv-tl:last-child { padding-bottom: 0; }
.ordv-tl:last-child::before { display: none; }
.ordv-tl__dot {
  position: relative;
  z-index: 1;
  width: 22px;
  height: 22px;
  border-radius: var(--r-full);
  border: 2px solid var(--n-200);
  background: var(--bg-surface);
  display: flex;
  align-items: center;
  justify-content: center;
}
.ordv-tl__dot svg {
  width: 12px;
  height: 12px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ordv-tl__label { display: block; font-size: var(--t-sm); font-weight: 600; color: var(--text-muted); line-height: 22px; }
.ordv-tl__time { display: block; font-size: var(--t-xs); color: var(--text-faint); margin-top: 1px; font-variant-numeric: tabular-nums; }
.ordv-tl--done .ordv-tl__dot { border-color: var(--ok-600); background: var(--ok-50); color: var(--ok-600); }
.ordv-tl--done .ordv-tl__label { color: var(--text-secondary); }
.ordv-tl--current .ordv-tl__dot {
  border-color: var(--brand-600);
  background: var(--brand-600);
  color: #fff;
  box-shadow: 0 0 0 4px var(--brand-50);
}
.ordv-tl--current .ordv-tl__label { color: var(--text); font-weight: 700; }
.ordv-tl--stopped .ordv-tl__dot {
  border-color: var(--danger-600);
  background: var(--danger-50);
  color: var(--danger-600);
}
.ordv-tl--stopped .ordv-tl__label { color: var(--danger-700); font-weight: 700; }

/* The action block at the foot of a rail card - the status select + apply
   pair, or "save prices" under the invoice totals. Stacked and full-width
   so the controls read as one action instead of stray widgets floating in
   a toolbar, and ruled off from the card body above them. */
.ordv-panel-foot {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ordv-panel-foot__label { font-size: var(--t-xs); font-weight: 600; color: var(--text-muted); }
.ordv-panel-foot__hint { font-size: var(--t-xs); color: var(--text-faint); line-height: 1.7; margin: 0; }
.ordv-panel-foot .db-select { width: 100%; }

/* Key/value list: the invoice summary on the order page, and the money
   panel (subtotal / discount / tax / total) on the invoice page. */
.ordv-kv { display: flex; flex-direction: column; gap: 9px; }
.ordv-kv__row { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: var(--t-sm); }
.ordv-kv__label { color: var(--text-muted); }
.ordv-kv__value { font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.ordv-kv__row .db-input { max-width: 132px; height: 34px; text-align: end; }
.ordv-kv__row--grand {
  border-top: 1px solid var(--border);
  margin-top: 3px;
  padding-top: 12px;
  font-size: var(--t-md);
}
.ordv-kv__row--grand .ordv-kv__label { color: var(--text); font-weight: 700; }
.ordv-kv__row--grand .ordv-kv__value { font-size: var(--t-lg); font-weight: 800; letter-spacing: -0.01em; }

/* Unit-price cell on a Draft invoice. Amounts are read as a column, so the
   inputs stay the same width as each other and end-aligned like the
   figures they replace. */
.ordv-price-input { max-width: 140px; height: 34px; text-align: end; margin-inline-start: auto; }

.ordv-note { font-size: var(--t-sm); color: var(--text-secondary); white-space: pre-line; margin: 0; }

/* Load-more footer under a paginated list. The row count next to the button
   is the honest part: it tells the operator how much of the table the search
   box above is actually searching. */
.db-load-more {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 16px 14px 4px;
}
.db-load-more__count { font-size: var(--t-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }

@media (max-width: 1100px) {
  .ordv-grid { grid-template-columns: minmax(0, 1fr) 290px; }
}
/* Below the split, the rail moves above the item list: on a phone the
   operator still wants status and actions first, and the items are what
   they scroll through afterwards. */
@media (max-width: 900px) {
  .ordv-grid { display: flex; flex-direction: column; }
  .ordv-side { position: static; order: -1; }
}
@media (max-width: 560px) {
  .ordv-head__title { font-size: var(--t-xl); }
  .ordv-head__actions { width: 100%; }
  .ordv-head__actions .db-btn { flex: 1; }
  .ordv-items__foot { justify-content: space-between; gap: 12px 18px; }
  .ordv-product__thumb { width: 34px; height: 34px; }
}

/* 10c. Agent dashboard ------------------------------------------------------
   An agent opens this screen to answer one question before anything else:
   "can I order right now, and until when?" So the window state is the hero -
   a full-width, state-coloured banner above the tiles - rather than a line
   of text in a card below them. The counts are context; the promotions are
   reference material, and sit last.
   ------------------------------------------------------------------------ */

.agd-window {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 18px 20px;
  border-radius: var(--r-lg);
  border: 1px solid var(--border);
  background: var(--bg-surface);
  box-shadow: var(--sh-xs);
  margin-bottom: 18px;
}
.agd-window__icon {
  width: 42px;
  height: 42px;
  border-radius: var(--r-md);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--n-100);
  color: var(--n-600);
}
.agd-window__icon svg {
  width: 20px;
  height: 20px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.agd-window__body { flex: 1; min-width: 200px; }
.agd-window__eyebrow {
  display: block;
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.01em;
  margin-bottom: 3px;
}
.agd-window__title {
  display: block;
  font-size: var(--t-lg);
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--text);
  margin: 0;
}
.agd-window__meta {
  display: block;
  font-size: var(--t-sm);
  color: var(--text-secondary);
  margin-top: 4px;
}
/* State lives on the icon chip and the eyebrow only - a full-bleed tinted
   banner would out-shout the brand-red order button sitting inside it. */
.agd-window--open { border-color: var(--ok-200); }
.agd-window--open .agd-window__icon { background: var(--ok-50); color: var(--ok-600); }
.agd-window--open .agd-window__eyebrow { color: var(--ok-600); }
.agd-window--upcoming { border-color: var(--warn-200); }
.agd-window--upcoming .agd-window__icon { background: var(--warn-50); color: var(--warn-600); }
.agd-window--upcoming .agd-window__eyebrow { color: var(--warn-600); }
.agd-window--closed .agd-window__eyebrow { color: var(--text-muted); }

/* Section heading with a trailing link ("see all"). */
.agd-section {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin: 26px 0 12px;
}

/* Promotion card - denser than a plain db-card: the badges, the name and
   the condition/reward lines are the whole content, so they get to sit
   close together instead of being spaced like a form. */
.agd-promo { display: flex; flex-direction: column; gap: 8px; }
.agd-promo__badges { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.agd-promo__title { font-size: var(--t-md); font-weight: 700; color: var(--text); margin: 2px 0 0; letter-spacing: -0.01em; }
.agd-promo__desc {
  font-size: var(--t-xs);
  color: var(--text-muted);
  margin: 0;
  line-height: 1.75;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.agd-promo__list {
  margin: 2px 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: var(--t-sm);
  line-height: 1.7;
}
.agd-promo__list li { display: flex; gap: 8px; }
/* Marker as a pseudo-element rather than a list bullet, so a wrapped second
   line aligns under the text and not under the dot. */
.agd-promo__list li::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: var(--r-full);
  background: var(--n-300);
  flex-shrink: 0;
  margin-top: 9px;
}
.agd-promo__list li.agd-promo__reward::before { background: var(--ok-600); }

@media (max-width: 640px) {
  .agd-window { padding: 16px; }
  .agd-window__actions, .agd-window__actions .db-btn { width: 100%; }
}

/* 11. Login --------------------------------------------------------------- */

.db-login-shell {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1fr;
  place-items: center;
  padding: 24px;
  background:
    radial-gradient(900px 520px at 80% -10%, rgba(237, 28, 36, 0.18), transparent 60%),
    radial-gradient(700px 500px at 10% 110%, rgba(53, 64, 90, 0.5), transparent 60%),
    linear-gradient(160deg, var(--nav-bg-soft), var(--nav-bg));
}

.db-login-card {
  width: 100%;
  max-width: 400px;
  background: var(--bg-surface);
  border-radius: var(--r-2xl);
  box-shadow: var(--sh-xl);
  padding: 32px 30px;
  border: 1px solid rgba(255, 255, 255, 0.4);
}

.db-login-card__brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin-bottom: 26px;
  text-align: center;
}

/* 12. Utilities ----------------------------------------------------------- */

.db-flex { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.db-flex--between { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.db-mt-2 { margin-top: 8px; }
.db-mt-4 { margin-top: 16px; }
.db-mt-6 { margin-top: 24px; }
.db-mb-4 { margin-bottom: 16px; }
.db-text-muted { color: var(--text-muted); }
.db-text-sm { font-size: var(--t-xs); }
.db-text-strong { font-weight: 600; color: var(--text); }
.db-num { font-variant-numeric: tabular-nums; }
.db-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.db-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* 13. Motion & print ------------------------------------------------------ */

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

@media print {
  .db-sidebar, .db-topbar, .db-form-actions,
  .ob-cart, .ob-filter-panel, .ob-bottom-bar, .oc-topbar,
  .ordv-panel-foot, .ordv-head__actions { display: none !important; }
  .db-content, .orv2-page { padding: 0; max-width: none; }
  .ordv-grid { display: block; }
  .ordv-side { position: static; }
  .db-card, .db-table-wrap { box-shadow: none; border-color: #ddd; }
  body { background: #fff; }
}

/* ---------------------------------------------------------------------------
   Returns
   
   The return builder is a list of things the agent already owns, not a
   catalogue to browse - so it reads as rows with a hard ceiling on each,
   rather than as a product grid. The ceiling is the whole point of the
   screen, so it is stated on every row whether or not it has been reached.
--------------------------------------------------------------------------- */

/* Order picker: one scannable row per order, so the order number, what is
   left, and how long remains all line up between rows. */
.rtn-picklist {
  display: flex; flex-direction: column; gap: 8px;
  margin-top: 4px;
}
.rtn-pickrow {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 16px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-xs);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.rtn-pickrow:hover {
  border-color: var(--accent-300);
  box-shadow: var(--sh-sm);
  transform: translateY(-1px);
}
.rtn-pickrow__icon {
  width: 40px; height: 40px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: var(--r-md);
  background: var(--accent-100); color: var(--accent-600);
}
.rtn-pickrow__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.rtn-pickrow__title { font-size: var(--t-md); font-weight: 700; }
.rtn-pickrow__sub {
  display: flex; flex-wrap: wrap; gap: 4px 12px;
  font-size: var(--t-xs); color: var(--text-muted);
}
/* The number is the reason this row is here, so it gets the visual weight. */
.rtn-pickrow__stat {
  flex-shrink: 0; text-align: center; line-height: 1.25;
  padding-inline: 14px;
  border-inline-start: 1px solid var(--border);
  border-inline-end: 1px solid var(--border);
}
.rtn-pickrow__stat-value {
  display: block; font-size: 20px; font-weight: 800; color: var(--ok-700);
  font-variant-numeric: tabular-nums;
}
.rtn-pickrow__stat-label { display: block; font-size: var(--t-2xs); color: var(--text-muted); }
.rtn-pickrow__deadline {
  flex-shrink: 0; min-width: 96px; text-align: center;
  font-size: var(--t-xs); font-weight: 600;
  color: var(--text-muted);
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  padding: 4px 10px;
}
/* Two days or fewer reads as a warning rather than a fact. */
.rtn-pickrow__deadline.is-urgent {
  color: var(--warn-700); background: var(--warn-50); border-color: var(--warn-200);
}
.rtn-pickrow.is-urgent { border-color: var(--warn-200); }
.rtn-pickrow__go {
  flex-shrink: 0; width: 8px; height: 8px;
  border-inline-start: 2px solid var(--n-300);
  border-block-end: 2px solid var(--n-300);
  transform: rotate(45deg);
}
.rtn-pickrow:hover .rtn-pickrow__go { border-color: var(--accent-600); }

@media (max-width: 720px) {
  .rtn-pickrow { flex-wrap: wrap; gap: 10px 12px; }
  .rtn-pickrow__main { flex: 1 1 100%; order: 1; }
  .rtn-pickrow__icon { order: 0; }
  .rtn-pickrow__stat {
    order: 2; text-align: start; padding-inline: 0;
    border: 0; display: flex; align-items: baseline; gap: 5px;
  }
  .rtn-pickrow__stat-value { font-size: var(--t-md); }
  .rtn-pickrow__deadline { order: 3; margin-inline-start: auto; }
  .rtn-pickrow__go { display: none; }
}

.rtn-deadline {
  display: flex; align-items: center; gap: 8px;
  margin-top: 14px; padding: 10px 14px;
  border: 1px solid var(--warn-200); background: var(--warn-50); color: var(--warn-700);
  border-radius: var(--r-md); font-size: var(--t-sm); font-weight: 600;
}

.rtn-lines { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }
.rtn-line {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px; border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--bg-surface);
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.rtn-line.is-selected { border-color: var(--accent-300); background: var(--accent-100); }
/* Spent lines stay visible but recede: an agent hunting for a product they
   already sent back needs to find it and see that it is spent, not wonder
   why it vanished. */
.rtn-line.is-spent { opacity: 0.55; }
.rtn-line__thumb {
  width: 46px; height: 46px; flex-shrink: 0;
  border-radius: var(--r-sm); background: var(--bg-sunken); object-fit: cover;
}
.rtn-line__body { flex: 1; min-width: 0; }
.rtn-line__title { font-size: var(--t-sm); font-weight: 600; display: flex; align-items: center; gap: 6px; }
.rtn-line__meta {
  display: flex; flex-wrap: wrap; gap: 4px 12px;
  margin-top: 3px; font-size: var(--t-xs); color: var(--text-muted);
}
.rtn-line__balance { font-weight: 700; color: var(--ok-700); }
.rtn-line__balance.is-zero { color: var(--text-faint); font-weight: 500; }
.rtn-line__reason { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 9px; }
.rtn-line__reason .db-select { flex: 0 0 auto; min-width: 190px; }
.rtn-line__reason .db-input { flex: 1; min-width: 160px; }

.rtn-summary {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 18px; padding: 14px 16px;
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--bg-surface); box-shadow: var(--sh-xs);
}
.rtn-summary__actions { margin-inline-start: auto; display: flex; gap: 10px; flex-wrap: wrap; }

/* Return detail pages use the shared .ordv-grid / .ordv-main / .ordv-side
   layout - the same two-column shape as order and invoice detail. */

.rtn-received { font-size: var(--t-xs); font-weight: 600; color: var(--ok-700); margin-top: 3px; }
/* A short receipt is the one number in this whole flow most worth noticing. */
.rtn-received.is-short { color: var(--warn-700); }

/* Status timelines use the shared .ordv-timeline styles - returns are not
   a different kind of status than orders and should not look like one. */

.rtn-order-requests { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.rtn-order-requests__title { font-size: var(--t-xs); font-weight: 700; color: var(--text-muted); margin-bottom: 8px; }
.rtn-order-request {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; margin-bottom: 6px;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--bg-subtle); font-size: var(--t-xs); font-weight: 600;
  color: inherit; text-decoration: none;
}
.rtn-order-request:hover { border-color: var(--accent-300); }
.rtn-order-request .db-badge { margin-inline-start: auto; }

.rtn-impact {
  display: flex; align-items: flex-start; gap: 9px;
  /* Needs a gap below as well as above - it sits directly on top of the
     detail grid, and flush against the next card it read as part of it. */
  margin: 14px 0 18px; padding: 12px 14px;
  border: 1px solid var(--warn-200); background: var(--warn-50); color: var(--warn-700);
  border-radius: var(--r-md); font-size: var(--t-sm); line-height: 1.8;
}

.rtn-excluded { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.rtn-excluded__row {
  display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--bg-subtle);
}
.rtn-excluded__why {
  margin-inline-start: auto; max-width: 60%;
  font-size: var(--t-xs); color: var(--warn-700); font-weight: 600; line-height: 1.7;
}

/* Notes written by a person, quoted rather than dumped as body text - it
   matters that an agent's explanation reads as *theirs* and not as system
   copy, especially next to the automated impact/violation messages. */
.rtn-note {
  margin: 0;
  padding: 11px 14px;
  border-inline-start: 3px solid var(--n-200);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  background: var(--bg-subtle);
  font-size: var(--t-sm);
  line-height: 1.9;
  color: var(--n-700);
  white-space: pre-line;
}
.rtn-note--danger {
  border-inline-start-color: var(--danger-600);
  background: var(--danger-50);
  color: var(--danger-700);
}
.rtn-note + .rtn-evidence { margin-top: 12px; }

/* Evidence as a thumbnail: on a damage claim the photo is the evidence, and
   a plain text link makes someone open a tab before they can judge it. */
.rtn-evidence {
  display: flex; align-items: center; gap: 12px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-surface);
  color: inherit; text-decoration: none;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.rtn-evidence:hover { border-color: var(--accent-300); box-shadow: var(--sh-xs); }
.rtn-evidence__thumb {
  width: 56px; height: 56px; flex-shrink: 0;
  border-radius: var(--r-sm); overflow: hidden; background: var(--bg-sunken);
}
.rtn-evidence__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rtn-evidence__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rtn-evidence__title { font-size: var(--t-sm); font-weight: 600; }
.rtn-evidence__hint { font-size: var(--t-xs); color: var(--text-muted); }

/* Jalali (Shamsi) date picker - replaces the native Gregorian
   <input type="date"> / datetime-local"> across the order/rule/window/
   returns/orders/invoices forms. See public/js/jalali.js for the Vue
   components. A day grid by default; clicking the header label zooms out
   to a month grid, then a year grid, for fast long-range jumps. */
.db-jdate { position: relative; }
.db-jdate__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  background: var(--bg-surface);
  text-align: start;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.db-jdate__trigger:hover { border-color: var(--n-300); }
.db-jdate__trigger.is-open { border-color: var(--brand-300); }
.db-jdate__trigger svg { width: 16px; height: 16px; stroke: var(--text-muted); fill: none; stroke-width: 1.8; flex-shrink: 0; }
.db-jdate__trigger span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.db-jdate__placeholder { color: var(--text-muted); }

.db-jdate-pop-enter-active, .db-jdate-pop-leave-active { transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease); }
.db-jdate-pop-enter-from, .db-jdate-pop-leave-to { opacity: 0; transform: translateY(-4px) scale(0.98); }

.db-jdate__panel {
  position: absolute;
  z-index: 60;
  top: calc(100% + 6px);
  inset-inline-start: 0;
  /* .is-flipped is set by placePanel() in jalali.js when the panel would
     run off the viewport on this edge - see the comment there. */
  width: 280px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-lg);
  padding: 12px;
}
.db-jdate__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  margin-bottom: 10px;
}
.db-jdate__label {
  font-size: var(--t-sm);
  font-weight: 700;
  color: var(--text);
  flex: 1;
  text-align: center;
  border-radius: var(--r-sm);
  padding: 4px 8px;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.db-jdate__label:hover:not(:disabled) { background: var(--bg-sunken); color: var(--brand-600); }
.db-jdate__label:disabled { cursor: default; }
.db-jdate__nav {
  width: 28px; height: 28px;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-sm);
  color: var(--text-secondary);
  font-size: 15px;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.db-jdate__nav:hover { background: var(--bg-sunken); color: var(--brand-600); }
.db-jdate__weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 4px;
}
.db-jdate__weekdays .is-weekend { color: var(--brand-600); }
.db-jdate__grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.db-jdate__grid--months { grid-template-columns: repeat(3, 1fr); gap: 6px; }
.db-jdate__cell {
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-sm);
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
  color: var(--text);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.db-jdate__cell:hover:not(:disabled) { background: var(--bg-sunken); }
.db-jdate__cell.is-empty { visibility: hidden; pointer-events: none; }
.db-jdate__cell.is-today { box-shadow: inset 0 0 0 1.5px var(--brand-300); font-weight: 700; }
.db-jdate__cell.is-selected { background: var(--brand-600); color: #fff; box-shadow: none; }
.db-jdate__cell--wide { aspect-ratio: auto; padding: 10px 4px; font-weight: 600; }
.db-jdate__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.db-jdate__link {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--brand-600);
  padding: 4px 8px;
  border-radius: var(--r-sm);
  transition: background var(--dur) var(--ease);
}
.db-jdate__link:hover { background: var(--bg-sunken); }
.db-jdate__link--danger { color: var(--danger-600); }

/* Date-range picker. Shares the single-date picker's panel chrome
   (.db-jdate__head / __weekdays / __grid--months) - only the day grid
   differs, because a range has to read as one continuous band rather than
   as seven unrelated cells per row. */
.db-jrange { position: relative; }
.db-jrange__trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  text-align: start;
  cursor: pointer;
  min-width: 210px;
}
.db-jrange__trigger:hover { border-color: var(--n-300); }
/* Open is a state, not an alarm: a single-pixel brand border says "this one
   is active" without the tinted glow that read as an error ring. Keyboard
   focus still gets the design system's real focus ring via :focus-visible. */
.db-jrange__trigger.is-open { border-color: var(--brand-300); }
/* A set range is worth signalling - it silently filters the table - but with
   weight on the label and icon rather than a coloured box. */
.db-jrange__trigger.is-set { border-color: var(--n-300); }
.db-jrange__trigger.is-set span { color: var(--text); font-weight: 600; }
.db-jrange__trigger svg { width: 16px; height: 16px; stroke: var(--text-muted); fill: none; stroke-width: 1.8; flex-shrink: 0; }
.db-jrange__trigger.is-set svg { stroke: var(--brand-600); }
.db-jrange__trigger span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.db-jrange__placeholder { color: var(--text-muted); }

.db-jdate__panel.is-flipped,
.db-jrange__panel.is-flipped { inset-inline-start: auto; inset-inline-end: 0; }

.db-jrange__panel {
  position: absolute;
  z-index: 60;
  top: calc(100% + 6px);
  inset-inline-start: 0;
  width: 310px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-lg);
  padding: 0 0 12px;
  overflow: hidden;
}

/* The two ends, restated at the top of the panel - while you are mid-pick
   the calendar is showing a moving span, and this is the part that says in
   words what you have actually committed to. */
.db-jrange__summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 14px 16px 12px;
}
.db-jrange__end { font-size: var(--t-sm); font-weight: 700; color: var(--text); white-space: nowrap; }
.db-jrange__end.is-empty { font-weight: 500; color: var(--text-faint); }
.db-jrange__arrow { color: var(--text-faint); font-size: 15px; line-height: 1; }

.db-jrange__grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  padding: 0 12px;
}
.db-jrange__cell {
  position: relative;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--t-sm);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  background: none;
  border: 0;
}
.db-jrange__cell.is-empty { pointer-events: none; }

/* The band. A pseudo-element rather than a background on the cell itself,
   so it can bleed the full width of the column and meet its neighbours with
   no seam, while the day number keeps its own circular hit area on top. */
.db-jrange__cell::before {
  content: '';
  position: absolute;
  inset: 3px 0;
  background: var(--brand-50);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.db-jrange__cell.is-in-range::before { opacity: 1; }
/* Logical radii, so the cap lands on the leading edge in RTL and on the
   trailing edge in LTR without a direction-specific rule. */
.db-jrange__cell.is-start::before,
.db-jrange__cell.is-row-start::before {
  border-start-start-radius: var(--r-full);
  border-end-start-radius: var(--r-full);
}
.db-jrange__cell.is-end::before,
.db-jrange__cell.is-row-end::before {
  border-start-end-radius: var(--r-full);
  border-end-end-radius: var(--r-full);
}
/* A one-day range is a lone circle, not a stub of band. */
.db-jrange__cell.is-start.is-end::before { opacity: 0; }

.db-jrange__day {
  position: relative;
  z-index: 1;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-full);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.db-jrange__cell:hover:not(.is-empty) .db-jrange__day { background: var(--n-100); color: var(--text); }
.db-jrange__cell.is-today .db-jrange__day { box-shadow: inset 0 0 0 1px var(--brand-200); color: var(--brand-600); }
.db-jrange__cell.is-start .db-jrange__day,
.db-jrange__cell.is-end .db-jrange__day,
.db-jrange__cell.is-start:hover .db-jrange__day,
.db-jrange__cell.is-end:hover .db-jrange__day {
  background: var(--brand-600);
  color: #fff;
  font-weight: 700;
  box-shadow: none;
}

/* One hairline separates the calendar from the controls under it. The
   presets and the reset used to be outlined pills, which put five more
   boxes inside a box that is already a box. */
.db-jrange__presets {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  padding: 12px 12px 0;
  margin-top: 8px;
  border-top: 1px solid var(--border);
}
.db-jrange__preset {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--bg-subtle);
  border-radius: var(--r-full);
  padding: 6px 12px;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.db-jrange__preset:hover { background: var(--brand-50); color: var(--brand-600); }

.db-jrange__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 12px 0;
}
.db-jrange__hint { font-size: var(--t-xs); color: var(--text-faint); }
.db-jrange__reset {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--text-secondary);
  border-radius: var(--r-sm);
  padding: 5px 10px;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.db-jrange__reset:hover:not(:disabled) { background: var(--bg-subtle); color: var(--brand-600); }
.db-jrange__reset:disabled { opacity: 0.4; cursor: not-allowed; }

/* On a narrow screen the panel would otherwise hang off the edge of the
   toolbar it is anchored to. */
@media (max-width: 420px) {
  .db-jrange__panel { width: min(310px, calc(100vw - 32px)); }
  .db-jrange__trigger { min-width: 0; }
}

.db-jdatetime { display: flex; gap: 8px; align-items: stretch; }
.db-jdatetime .db-jdate { flex: 1; min-width: 0; }
.db-jdatetime__time { width: 108px; flex-shrink: 0; }

/* ---------------------------------------------------------------------------
   Sample requests

   The allowance banner is the first thing on these screens because it decides
   whether the primary action will work at all - an agent who is out of quota
   should learn that before filling in a form, not after submitting it.
--------------------------------------------------------------------------- */
.smp-quota {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 14px; padding: 11px 14px;
  border: 1px solid var(--ok-100); background: var(--ok-50); color: var(--ok-700);
  border-radius: var(--r-md); font-size: var(--t-sm); font-weight: 600;
}
.smp-quota.is-spent { border-color: var(--warn-200); background: var(--warn-50); color: var(--warn-700); }
.smp-quota__meter { margin-inline-start: auto; display: flex; align-items: center; gap: 8px; }
.smp-quota__bar {
  width: 90px; height: 5px; border-radius: 999px;
  background: rgba(0, 0, 0, 0.08); overflow: hidden; display: block;
}
.smp-quota__bar > span { display: block; height: 100%; background: currentColor; border-radius: 999px; }
.smp-quota__count { font-variant-numeric: tabular-nums; font-size: var(--t-xs); }

.smp-group { margin-top: 16px; }
.smp-group__title {
  font-size: var(--t-xs); font-weight: 700; color: var(--text-muted);
  padding-bottom: 6px; margin-bottom: 8px; border-bottom: 1px solid var(--border);
}
.smp-group .rtn-line { margin-bottom: 8px; }
.smp-due { color: var(--warn-700); font-weight: 700; }

/* ---------------------------------------------------------------------------
   Segmented choice: one option of a small mutually-exclusive set.

   Built on real <input type="radio"> elements, visually hidden rather than
   replaced. Arrow-key navigation within the group, focus handling, and
   screen-reader grouping all come free from the native control; hand-rolling
   those on divs is how a good-looking picker becomes an unusable one.

   Each option carries its own tone so the choice reads at a glance - grey for
   a private draft, amber for a trial, green for live - which is the whole
   advantage over a select: the states are visible without opening anything.
--------------------------------------------------------------------------- */
.db-choice-group {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin-top: 4px;
}
.db-choice {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1.5px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-surface);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.db-choice:hover { border-color: var(--n-300); background: var(--bg-subtle); }

/* Hidden, not removed - see the note above. */
.db-choice__input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}

/* The dot. Its ring collapses into a filled centre when chosen, which is the
   one bit of the native control worth keeping the look of. */
.db-choice__mark {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  border-radius: 50%;
  border: 2px solid var(--n-300);
  background: var(--bg-surface);
  display: grid;
  place-items: center;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.db-choice__mark::after {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: transparent;
  transform: scale(0.4);
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease);
}
.db-choice__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.db-choice__title { font-size: var(--t-sm); font-weight: 600; color: var(--n-700); }
.db-choice__hint { font-size: var(--t-xs); color: var(--text-muted); }

.db-choice.is-selected { box-shadow: var(--sh-xs); }
.db-choice.is-selected .db-choice__mark::after { transform: scale(1); }
.db-choice.is-selected .db-choice__title { font-weight: 700; }

/* Keyboard focus has to be visible on the card, since the input it belongs to
   is not. */
.db-choice__input:focus-visible + .db-choice__mark {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}

/* Per-state tones. */
.db-choice--draft.is-selected {
  border-color: var(--n-300);
  background: var(--bg-subtle);
}
.db-choice--draft.is-selected .db-choice__mark { border-color: var(--n-500); }
.db-choice--draft.is-selected .db-choice__mark::after { background: var(--n-500); }

.db-choice--trial.is-selected {
  border-color: var(--warn-200);
  background: var(--warn-50);
}
.db-choice--trial.is-selected .db-choice__mark { border-color: var(--warn-600); }
.db-choice--trial.is-selected .db-choice__mark::after { background: var(--warn-600); }
.db-choice--trial.is-selected .db-choice__title { color: var(--warn-700); }

.db-choice--live.is-selected {
  border-color: var(--ok-100);
  background: var(--ok-50);
}
.db-choice--live.is-selected .db-choice__mark { border-color: var(--ok-600); }
.db-choice--live.is-selected .db-choice__mark::after { background: var(--ok-600); }
.db-choice--live.is-selected .db-choice__title { color: var(--ok-700); }

/* A checkbox that is present but not currently meaningful - shown rather than
   hidden, so its absence never looks like a missing feature. */
.db-check.is-disabled { opacity: 0.55; cursor: default; }
.db-check.is-disabled input { cursor: default; }


.db-modal__body {
  margin: 0 0 4px;
  font-size: var(--t-sm);
  line-height: 1.9;
  color: var(--text-secondary, var(--n-700));
}

/* Item 3: the quota banner is a statement, the toolbar below is a control -
   they were touching, which read as one block. */
.smp-quota { margin-bottom: 18px; }
.smp-quota + .db-toolbar { margin-top: 0; }

/* Item 4: the shipping note needs air between it and the dates above, and the
   same quoted treatment every other human-written note in the app gets. */
.smp-shipping-note { margin-top: 16px; }

/* Item 6: the sample builder's primary action, kept in reach at the top of a
   long catalogue instead of buried under it. */
.smp-actionbar {
  position: sticky;
  /* Below the sticky topbar, not underneath it. `top: 12px` parked this
     halfway behind the header, which is exactly where a primary action must
     not be; the offset has to clear the topbar's own height. */
  top: calc(var(--topbar-h) + 12px);
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 14px;
  padding: 12px 16px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-sm);
}
.smp-actionbar__info { font-size: var(--t-sm); }
.smp-actionbar .db-btn { margin-inline-start: auto; }
.smp-actionbar__hint { margin: 6px 2px 0; text-align: start; }

/* ---------------------------------------------------------------------------
   Dashboard "new products" banner.

   Accent-tinted rather than neutral: an experimental product exists nowhere
   else in the agent's world - not the order builder, not the public site - so
   this is the only place they can discover it, and it has to read as news
   rather than as another statistic tile.
--------------------------------------------------------------------------- */
/* Section spacing on the dashboard comes from .agd-section's own margins, so
   the banner adds none of its own - blocks that each carry a bespoke margin
   are how a page ends up with four different gaps between five sections. */
.agd-new {
  padding: 16px 18px;
  border: 1px solid var(--accent-300);
  border-radius: var(--r-xl);
  background: var(--accent-100);
}
.agd-new__head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.agd-new__headtext { min-width: 0; flex: 1; }
.agd-new__icon {
  width: 40px; height: 40px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: var(--r-md);
  background: var(--bg-surface); color: var(--accent-600);
}
.agd-new__title { display: block; font-size: var(--t-md); }
.agd-new__sub { font-size: var(--t-xs); color: var(--n-700); margin-top: 3px; line-height: 1.8; }
.agd-new__cta { margin-inline-start: auto; flex-shrink: 0; }

.agd-new__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 8px;
  margin-top: 14px;
}
.agd-new__item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  border-radius: var(--r-md);
  background: var(--bg-surface);
  border: 1px solid transparent;
  color: inherit; text-decoration: none;
  transition: border-color var(--dur) var(--ease);
}
.agd-new__item:hover { border-color: var(--accent-300); }
.agd-new__thumb {
  width: 38px; height: 38px; flex-shrink: 0;
  border-radius: var(--r-sm); object-fit: cover;
  background: var(--bg-sunken); display: block;
}
.agd-new__item-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.agd-new__item-title {
  font-size: var(--t-sm); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.agd-new__item-meta { font-size: var(--t-2xs); color: var(--text-muted); }

@media (max-width: 620px) {
  .agd-new__cta { margin-inline-start: 0; width: 100%; justify-content: center; }
}
